home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 2010 Software/Programs / PCGuia_programas.iso / Software / Utils / Advanced SystemCare / asc-setup.exe / {app} / tb / lib / xpcom.js
Encoding:
Text File  |  2009-12-23  |  502.1 KB  |  12,574 lines

  1.  
  2. var Logging =
  3. {
  4.     LogToConsole: function(ex, addInfo) {
  5.         if (!PrefService.GetPref("conduit.debugMode")) return;
  6.  
  7.         if (ex && typeof ex.fileName != "undefined") {
  8.             var strMsg = addInfo + " " + ex + "\nStack:\n " + ex.stack;
  9.             this.ExtendedLogToConsole(strMsg, ex.fileName, null, ex.lineNumber, null, null, ex.name);
  10.         }
  11.         else
  12.             this.ExtendedLogToConsole(ex, null, null, null, null, null, null);
  13.     },
  14.  
  15.     ExtendedLogToConsole: function(aMessage, aSourceName, aSourceLine, aLineNumber, aColumnNumber, aFlags, aCategory) {
  16.         var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
  17.                                  .getService(Components.interfaces.nsIConsoleService);
  18.         var scriptError = Components.classes["@mozilla.org/scripterror;1"]
  19.                               .createInstance(Components.interfaces.nsIScriptError);
  20.         scriptError.init(aMessage, aSourceName, aSourceLine, aLineNumber,
  21.                    aColumnNumber, aFlags, aCategory);
  22.  
  23.         consoleService.logMessage(scriptError);
  24.     },
  25.  
  26.     //DB error log
  27.     DBLogToConsole: function(tableName, error, ex, moreInfo) {
  28.         var strMsg = stringFormat("DB Error\nTable name:{0}\n{1}\n{2}\n{3}", tableName, error, ex, moreInfo);
  29.         this.LogToConsole(strMsg);
  30.     }
  31. };
  32.  
  33. function EBLog(ex, addInfo) {
  34.     Logging.LogToConsole(ex, addInfo);
  35. };
  36. var AppInfo =
  37. {
  38.     //consts
  39.     WIN: "WIN",
  40.     MAC: "MAC",
  41.     LINUX: "LINUX",
  42.  
  43.     //public properties
  44.     OS: "",
  45.     browserVersion: "",
  46.     isGecko191: null, //FF3.5 and up
  47.     isGecko19: null, //FF3 and up
  48.     isGecko18: null, //FF2 and up
  49.  
  50.     xulRuntime: null,
  51.  
  52.     compareVersions: function(strVer1, strVer2) {
  53.         var oVersionCompare = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
  54.                                         .createInstance(Components.interfaces.nsIVersionComparator);
  55.         return oVersionCompare.compare(strVer1, strVer2);
  56.     },
  57.  
  58.     getOS: function() {
  59.         try {
  60.             var window = getWindow();
  61.             var strUserAgent = window.navigator.userAgent;
  62.             var iStart = strUserAgent.indexOf('(');
  63.             var iEnd = strUserAgent.indexOf(')');
  64.             var strPlatformData = strUserAgent.substring(iStart, iEnd);
  65.             var arrData = strPlatformData.split(';');
  66.             return arrData[2].replace(/\s/g, "");
  67.         }
  68.         catch (e) {
  69.             return "";
  70.         }
  71.     },
  72.  
  73.     isVista: function() {
  74.         var os = this.getOS().toUpperCase();
  75.         if (os.indexOf(this.WIN) == -1)
  76.             return false;
  77.  
  78.         os = os.replace(/\./g, "");
  79.         var ver = os.match(/(\d+)/);
  80.         return parseInt(ver) >= 60
  81.     },
  82.  
  83.     init: function() {
  84.  
  85.         //parse OS type
  86.         try {
  87.             this.xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime);
  88.             var _os = this.xulRuntime.OS.toUpperCase();
  89.             if (_os.indexOf(this.WIN) != -1) {
  90.                 this.OS = this.WIN;
  91.             }
  92.             else if (_os.indexOf(this.MAC) != -1)
  93.                 this.OS = this.MAC;
  94.             else
  95.                 this.OS = this.LINUX;
  96.  
  97.             //set gecko version (1.8.x or 1.9.x)
  98.             var _geckoVer = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo).platformVersion;
  99.             this.browserVersion = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo).version;
  100.  
  101.             var strGeckoVer = "1.9.0.0"; //FF3 gecko version
  102.             var iCompare = this.compareVersions(_geckoVer, strGeckoVer);
  103.             this.isGecko19 = (iCompare >= 0);
  104.  
  105.             strGeckoVer = "1.9.1.0"; //FF3.5 gecko version
  106.             var iCompare = this.compareVersions(_geckoVer, strGeckoVer);
  107.             this.isGecko191 = (iCompare >= 0);
  108.  
  109.             strGeckoVer = "1.8.0.0"; //FF2 gecko version
  110.             iCompare = this.compareVersions(_geckoVer, strGeckoVer);
  111.             this.isGecko18 = (iCompare >= 0);
  112.  
  113.         } catch (e) { Logging.LogToConsole(e) }
  114.     }
  115. };
  116.  
  117. AppInfo.init();
  118.  
  119.  
  120. var CommonFolderManagment =
  121. {
  122.     cleanup: function() {
  123.         try {
  124.             var oDir = Dir.get("ProfD");
  125.             oDir.append(CommonData.ConduitFolder);
  126.             var arrFiles = Dir.read(oDir, true);
  127.  
  128.             Dir.unlink(oDir, true);
  129.         }
  130.         catch (ex) {
  131.             EBLog(ex);
  132.         }
  133.     }
  134. };
  135. function FeedCustomData(strTitle, strLink, strImageUrl) {
  136.     this.title = strTitle;
  137.     this.link = strLink;
  138.     this.imageUrl = strImageUrl;
  139. };
  140. function FeedCustomItem() {
  141.     this.title = "";
  142.     this.link = "";
  143.     this.pubDate = "";
  144.     this.description = "";
  145.     this.guid = "";
  146.     this.isHistory = false;
  147.  
  148.     this.initFromItem = function(feedItem) {
  149.     this.link = (feedItem.link) ? feedItem.link.resolve("") : "";
  150.     this.title = (feedItem.title) ? feedItem.title.text : "";
  151.         //patch to grab the published date
  152.         this.pubDate = (feedItem.published) ? feedItem.published : feedItem.fields.getPropertyAsAString("pubDate");
  153.         this.description = (feedItem.summary) ? feedItem.summary.text : feedItem.content.text;
  154.         this.guid = feedItem.id;
  155.     };
  156.  
  157.     this.init = function(title, link, description, pubDate, guid) {
  158.         this.link = link;
  159.         this.title = title;
  160.         this.description = description;
  161.         this.pubDate = pubDate;
  162.         this.guid = guid;
  163.     };
  164. };
  165. var FeedParser = {
  166.     //this function returns an Array of FeedCustomItem, with 2 more properties:
  167.     //title, link
  168.     parseFeed: function(strFeedText, strUrl, isPodcast, objCallback, objCallbackThis, state) {
  169.         //parse with build in Web Feed Api
  170.         if (AppInfo.isGecko18)
  171.             return this._parseFeedNative(strFeedText, strUrl, isPodcast, objCallback, objCallbackThis, state);
  172.         else
  173.             return this._parseFeedFFBelow2(strFeedText, strUrl, isPodcast, objCallback, objCallbackThis, state);
  174.     },
  175.  
  176.     _parseFeedNative: function(strFeedText, strUrl, isPodcast, objCallback, objCallbackThis, state) {
  177.         var FeedResultListener = function(objCallback, objCallbackThis) {
  178.             //feed parser function
  179.             this.handleResult = function(result) {
  180.                 var feed = result.doc;
  181.                 feed.QueryInterface(Components.interfaces.nsIFeed);
  182.                 var itemArray = feed.items;
  183.                 var customItemArray = new Array();
  184.                 var numItems = itemArray.length;
  185.                 var item = null;
  186.                 var feedCustomItem = null;
  187.                 for (var i = 0; i < numItems; i++) {
  188.                     item = itemArray.queryElementAt(i, Components.interfaces.nsIFeedEntry);
  189.                     feedCustomItem = new FeedCustomItem();
  190.                     feedCustomItem.initFromItem(item);
  191.                     customItemArray.push(feedCustomItem);
  192.                 }
  193.  
  194.                 customItemArray.feedData = new FeedCustomData((feed.title) ? feed.title.plainText() : "",
  195.                                                                 (feed.link) ? feed.link.resolve("") : "",
  196.                                                                 (feed.image) ? feed.image.getPropertyAsAString("url") : ""
  197.                                                              );
  198.  
  199.                 objCallback.call(objCallbackThis, customItemArray, state);
  200.             }
  201.         };
  202.  
  203.         var resultListener = new FeedResultListener(objCallback, objCallbackThis);
  204.         var fp = Components.classes["@mozilla.org/feed-processor;1"].createInstance(Components.interfaces.nsIFeedProcessor);
  205.         fp.listener = resultListener;
  206.         fp.parseFromString(strFeedText, getURI(strUrl));
  207.     },
  208.  
  209.     _parseFeedFFBelow2: function(strFeedText, strUrl, isPodcast, objCallback, objCallbackThis, state) {
  210.         //TODO: take a code from toolbar feed parsing
  211.     }
  212. }
  213. //this object receives url of the feed, and callback function, to call when feed is processed, passing
  214. //the processed feed nsIFeedContainer as a parameter.
  215. function FeedPoller(strUrl, isPodcast, objCallback, objCallbackThis, state) {
  216.     this.onFeedDataAvailable = function(strFeedData) {
  217.         FeedParser.parseFeed(strFeedData, strUrl, isPodcast, objCallback, objCallbackThis, state);
  218.     };
  219.  
  220.     var self = this;
  221.     EBServerDataURL.HTTPServerRequest(strUrl, null, false, function(strFeedData) { self.onFeedDataAvailable(strFeedData); });
  222. };
  223. function HashArray(saveKeysInArray) {
  224.     this.IndexerArray = null;
  225.     this.HashArray = null;
  226.     this.KeysArray = null;
  227.  
  228.     this.Init = function() {
  229.         this.IndexerArray = new Array();
  230.         this.HashArray = new Array();
  231.         this.KeysArray = new Array();
  232.     };
  233.  
  234.     this.Add = function(strKeyID, objValue) {
  235.         //check if already exists
  236.         if (!this.Contains(strKeyID)) {
  237.             strKeyID = this.LegalizeHashKey(strKeyID);
  238.  
  239.             //add to the indexers array to the last place
  240.             this.IndexerArray[this.IndexerArray.length] = objValue;
  241.  
  242.             //add to the hash array per component id
  243.             this.HashArray[strKeyID] = objValue;
  244.  
  245.             if (saveKeysInArray) this.KeysArray.push(strKeyID);
  246.         }
  247.     };
  248.  
  249.     this.Insert = function(iIndex, strKeyID, objValue) {
  250.         if (!this.Contains(strKeyID)) {
  251.             strKeyID = this.LegalizeHashKey(strKeyID);
  252.  
  253.             //add to the indexers array to the iIndex place
  254.             this.IndexerArray.splice(iIndex, 0, objValue);
  255.  
  256.             //add to the hash array per component id
  257.             this.HashArray[strKeyID] = objValue;
  258.  
  259.             if (saveKeysInArray) this.KeysArray.push(strKeyID);
  260.         }
  261.     };
  262.  
  263.     this.Remove = function(iIndex, strKeyID) {
  264.         if (this.Contains(strKeyID)) {
  265.             strKeyID = this.LegalizeHashKey(strKeyID);
  266.  
  267.             //remove from indexer array
  268.             this.IndexerArray.splice(iIndex, 1);
  269.  
  270.             //remove from hash
  271.             delete this.HashArray[strKeyID];
  272.         }
  273.  
  274.     };
  275.  
  276.     this.GetByIndex = function(iIndex) {
  277.         var objValue = this.IndexerArray[iIndex];
  278.         return objValue;
  279.     };
  280.  
  281.     this.GetByID = function(strKeyID) {
  282.         strKeyID = this.LegalizeHashKey(strKeyID);
  283.  
  284.         var objValue = this.HashArray[strKeyID];
  285.         return objValue;
  286.     };
  287.  
  288.     this.GetIndexByObjectValue = function(oValue) {
  289.         for (var i = 0; i < this.IndexerArray.length; i++) {
  290.             if (this.GetByIndex(i) == oValue) {
  291.                 return i;
  292.             }
  293.         }
  294.  
  295.         return -1;
  296.     };
  297.  
  298.     this.Contains = function(strKeyID) {
  299.         var objValue = this.GetByID(strKeyID);
  300.         return objValue ? true : false;
  301.     };
  302.  
  303.     this.Count = function() {
  304.         return this.IndexerArray.length;
  305.     };
  306.  
  307.     this.LegalizeHashKey = function(strKeyID) {
  308.         try {
  309.             strKeyID = strKeyID.toString();
  310.             strKeyID = strKeyID.toUpperCase();
  311.         }
  312.         catch (ex) {
  313.             Logging.LogToConsole(ex);
  314.         }
  315.  
  316.         return strKeyID;
  317.     };
  318.  
  319.     this.Clear = function() {
  320.         this.Init();
  321.     };
  322.  
  323.     this.Init();
  324. }
  325. //this object is not real hash, it's used for little amount of data, but can delete from the hash.
  326. function HashArray2() {
  327.     this.arr = null;
  328.  
  329.     this.Init = function() {
  330.         this.arr = new Array();
  331.     };
  332.  
  333.     this.Add = function(strKeyID, objValue) {
  334.         strKeyID = this.LegalizeHashKey(strKeyID);
  335.         
  336.         //remove if already exists
  337.         this.Remove(strKeyID);
  338.  
  339.         this.arr.push({ "key": strKeyID, "value": objValue });
  340.     };
  341.  
  342.     this.Remove = function(strKeyID) {
  343.         strKeyID = this.LegalizeHashKey(strKeyID);
  344.         var elem = null;
  345.  
  346.         var temp = this._getObjAndIndex(strKeyID);
  347.         if (!temp) return;
  348.  
  349.         this.arr.splice(temp.index, 1);
  350.     };
  351.  
  352.     this.GetByIndex = function(iIndex) {
  353.         return this.arr[iIndex].value;
  354.     };
  355.  
  356.     this.GetByID = function(strKeyID) {
  357.         strKeyID = this.LegalizeHashKey(strKeyID);
  358.         var temp = this._getObjAndIndex(strKeyID);
  359.         if (!temp) throw ("element not found in hash");
  360.         return temp.obj.value;
  361.     };
  362.  
  363.     this.Contains = function(strKeyID) {
  364.         strKeyID = this.LegalizeHashKey(strKeyID);
  365.         return this._getObjAndIndex(strKeyID) != null;
  366.     };
  367.  
  368.     this.Count = function() {
  369.         return this.arr.length;
  370.     };
  371.  
  372.     this.LegalizeHashKey = function(strKeyID) {
  373.         try {
  374.             strKeyID = strKeyID.toString();
  375.             strKeyID = strKeyID.toUpperCase();
  376.         }
  377.         catch (ex) {
  378.             Logging.LogToConsole(ex);
  379.         }
  380.  
  381.         return strKeyID;
  382.     };
  383.  
  384.     this._getObjAndIndex = function(strKeyID) {
  385.         strKeyID = this.LegalizeHashKey(strKeyID);
  386.         for (var i = 0; i < this.arr.length; i++) {
  387.             elem = this.arr[i];
  388.             if (elem.key == strKeyID) {
  389.                 return { "obj": elem, "index": i };
  390.             }
  391.         }
  392.         return null;
  393.     };
  394.     
  395.     this.Clear = function() {
  396.         this.Init();
  397.     };
  398.  
  399.     this.Init();
  400.  
  401. }
  402. function IdleObserver(iTimout, onIdleCallback, onBackCallback, objThis) {
  403.     var NSIObserverService = Components.classes["@mozilla.org/widget/idleservice;1"].getService(Components.interfaces["nsIIdleService"]);
  404.     this.isIdle = false;
  405.  
  406.     this.register = function() {
  407.         NSIObserverService.addIdleObserver(this, iTimout);
  408.     };
  409.  
  410.     this.unregister = function() {
  411.         NSIObserverService.removeIdleObserver(this, iTimout);
  412.     };
  413.  
  414.     this.observe = function(aSubject, aTopic, idleTime) {
  415.         if (aTopic == "idle") {
  416.             this.isIdle = true;
  417.             onIdleCallback.call(objThis, idleTime);
  418.         }
  419.         else if (aTopic == "back") {
  420.             this.isIdle = false;
  421.             onBackCallback.call(objThis, idleTime);
  422.         }
  423.     };
  424.  
  425.     this.getIddleTime = function() {
  426.         return NSIObserverService.idleTime;
  427.     };
  428. };
  429.  
  430. IdleObserver.prototype = new BaseObserver();
  431. function IO(strOriginalCTID, strCurrentCTID) {
  432.     this.basePath = "";
  433.     this.baseMCPath = "";
  434.  
  435. //*************** Public methods *********************
  436.     
  437.     //returns file content as string
  438.     this.readToolbarFile = function(strRelativePath, isMC, charset) {
  439.         var oFile = this._getFile(strRelativePath, isMC);
  440.  
  441.         if (!oFile)
  442.             return "";
  443.         else
  444.             return File.read(oFile, charset);
  445.     };
  446.  
  447.     this.writeToolbarFile = function(strData, strRelativePath, isMC, charset) {
  448.         var oFile = this._getFile(strRelativePath, isMC);
  449.         if (!oFile) return;
  450.  
  451.         File.write(oFile, strData, null, charset);
  452.     };
  453.  
  454.     this.isExists = function(strRelativePath, isMC) {
  455.         try {
  456.             var oFile = null;
  457.             oFile = File.open(this._getBaseDirPath(isMC) + Dir.sep + strRelativePath);
  458.             return oFile.exists();
  459.         }
  460.         catch (e) {
  461.             return false;
  462.         }
  463.     };
  464.  
  465.     this.isExistsNotEmpty = function(strRelativePath, isMC) {
  466.         if (!this.isExists(strRelativePath, isMC))
  467.             return false;
  468.  
  469.         var strData = this.readToolbarFile(strRelativePath, isMC);
  470.         if (strData && strData.length > 0)
  471.             return true;
  472.         else
  473.             return false;
  474.     };
  475.  
  476.     this.deleteFile = function(strRelativePath, isMC) {
  477.         if (!this.isExists(strRelativePath, isMC)) return;
  478.  
  479.         var oFile = this._getFile(strRelativePath, isMC);
  480.         if (oFile) File.unlink(oFile);
  481.     };
  482.     
  483. //*************** Private methods *********************
  484.  
  485.     this._init = function(strOriginalCTID, strCurrentCTID) {
  486.         this.basePath = IOManager.GetPrefsDir().path + Dir.sep + strOriginalCTID;
  487.         if (strOriginalCTID != strCurrentCTID)
  488.             this.baseMCPath = this.basePath + Dir.sep + "communities" + Dir.sep + strCurrentCTID;
  489.         else
  490.             this.baseMCPath = this.basePath;
  491.  
  492.         //create base dirs if not exists
  493.         var oToolbarDir = Dir.open(this.basePath);
  494.         if (!oToolbarDir.exists())
  495.             Dir.create(oToolbarDir);
  496.  
  497.         oToolbarDir = Dir.open(this.baseMCPath)
  498.         if (!oToolbarDir.exists())
  499.             Dir.create(oToolbarDir);
  500.  
  501.     };
  502.  
  503.     this._getBaseDirPath = function(isMC) {
  504.         return (isMC) ? this.baseMCPath : this.basePath;
  505.     };
  506.  
  507.     this._getFile = function(strRelativePath, isMC) {
  508.         try {
  509.             var oFile = null;
  510.             oFile = File.open(this._getBaseDirPath(isMC) + Dir.sep + strRelativePath);
  511.  
  512.             if (!oFile.exists())
  513.                 File.create(oFile);
  514.  
  515.             return oFile;
  516.         }
  517.         catch (ex) {
  518.             return null;
  519.         }
  520.     };
  521.     
  522.     //init class
  523.     this._init(strOriginalCTID, strCurrentCTID);
  524. };
  525. var File =
  526.     {
  527.  
  528.         defaultCharSet: "UTF-8",
  529.  
  530.         localfileCID: '@mozilla.org/file/local;1',
  531.         localfileIID: Components.interfaces.nsILocalFile,
  532.  
  533.         finstreamCID: '@mozilla.org/network/file-input-stream;1',
  534.         finstreamIID: Components.interfaces.nsIFileInputStream,
  535.  
  536.         foutstreamCID: '@mozilla.org/network/file-output-stream;1',
  537.         foutstreamIID: Components.interfaces.nsIFileOutputStream,
  538.  
  539.         sinstreamCID: '@mozilla.org/scriptableinputstream;1',
  540.         sinstreamIID: Components.interfaces.nsIScriptableInputStream,
  541.  
  542.         suniconvCID: '@mozilla.org/intl/scriptableunicodeconverter',
  543.         suniconvIID: Components.interfaces.nsIScriptableUnicodeConverter,
  544.  
  545.         open: function(path) {
  546.             try {
  547.                 var file = Components.classes[this.localfileCID]
  548.                                 .createInstance(this.localfileIID);
  549.                 file.initWithPath(path);
  550.                 return file;
  551.             }
  552.             catch (e) {
  553.                 return false;
  554.             }
  555.         },
  556.  
  557.         read: function(file, charset) {
  558.             try {
  559.                 if (typeof charset == "undefined") charset = this.defaultCharSet;
  560.  
  561.                 var data = new String();
  562.                 var fiStream = Components.classes[this.finstreamCID]
  563.                                     .createInstance(this.finstreamIID);
  564.                 var siStream = Components.classes[this.sinstreamCID]
  565.                                     .createInstance(this.sinstreamIID);
  566.                 fiStream.init(file, 1, 0, false);
  567.                 siStream.init(fiStream);
  568.                 data += siStream.read(-1);
  569.                 siStream.close();
  570.                 fiStream.close();
  571.                 if (charset) {
  572.                     data = this.toUnicode(data, charset);
  573.                 }
  574.                 return data;
  575.             }
  576.             catch (e) {
  577.                 EBLog(e, "file read error");
  578.                 return false;
  579.             }
  580.         },
  581.  
  582.         write: function(file, data, mode, charset) {
  583.             try {
  584.                 if (typeof charset == "undefined") charset = this.defaultCharSet;
  585.  
  586.                 var foStream = Components.classes[this.foutstreamCID]
  587.                                     .createInstance(this.foutstreamIID);
  588.                 if (charset)
  589.                     data = this.fromUnicode(data, charset);
  590.  
  591.                 var flags = 0x02 | 0x08 | 0x20; // wronly | create | truncate
  592.                 if (mode == 'a') {
  593.                     flags = 0x02 | 0x10; // wronly | append
  594.                 }
  595.                 foStream.init(file, flags, 0664, 0);
  596.                 foStream.write(data, data.length);
  597.                 // foStream.flush();
  598.                 foStream.close();
  599.                 return true;
  600.             }
  601.             catch (e) {
  602.                 EBLog(e, "file write error");
  603.                 return false;
  604.             }
  605.         },
  606.  
  607.         create: function(file) {
  608.             try {
  609.                 file.create(0x00, 0664);
  610.                 return true;
  611.             }
  612.             catch (e) {
  613.                 return false;
  614.             }
  615.         },
  616.  
  617.         unlink: function(file) {
  618.             try {
  619.                 file.remove(false);
  620.                 return true;
  621.             }
  622.             catch (e) {
  623.                 return false;
  624.             }
  625.         },
  626.  
  627.         path: function(file) {
  628.             try {
  629.                 return 'file:///' + file.path.replace(/\\/g, '\/')
  630.                             .replace(/^\s*\/?/, '').replace(/\ /g, '%20');
  631.             }
  632.             catch (e) {
  633.                 return false;
  634.             }
  635.         },
  636.  
  637.         toUnicode: function(data, charset) {
  638.             try {
  639.                 if (typeof charset == "undefined") charset = this.defaultCharSet;
  640.  
  641.                 var uniConv = Components.classes[this.suniconvCID]
  642.                                     .createInstance(this.suniconvIID);
  643.                 uniConv.charset = charset;
  644.                 data = uniConv.ConvertToUnicode(data);
  645.             }
  646.             catch (e) {
  647.                 // foobar!
  648.             }
  649.             return data;
  650.         },
  651.  
  652.         fromUnicode: function(data, charset) {
  653.             try {
  654.                 if (typeof charset == "undefined") charset = this.defaultCharSet;
  655.                 var uniConv = Components.classes[this.suniconvCID]
  656.                                     .createInstance(this.suniconvIID);
  657.                 uniConv.charset = charset;
  658.                 data = uniConv.ConvertFromUnicode(data);
  659.                 // data += uniConv.Finish();
  660.             }
  661.             catch (e) {
  662.                 // foobar!
  663.             }
  664.             return data;
  665.         }
  666.  
  667.     }
  668.  
  669. var Dir =
  670. {
  671.  
  672.     sep: '/',
  673.  
  674.     dirservCID: '@mozilla.org/file/directory_service;1',
  675.  
  676.     propsIID: Components.interfaces.nsIProperties,
  677.  
  678.     fileIID: Components.interfaces.nsIFile,
  679.  
  680.     get: function(type) {
  681.         try {
  682.             var dir = Components.classes[this.dirservCID]
  683.                             .createInstance(this.propsIID)
  684.                             .get(type, this.fileIID);
  685.             return dir;
  686.         }
  687.         catch (e) {
  688.             return false;
  689.         }
  690.     },
  691.  
  692.     open: function(path) {
  693.         return File.open(path);
  694.     },
  695.  
  696.     create: function(dir) {
  697.         try {
  698.             dir.create(0x01, 0755);
  699.             //make sure we can read and write to and from the directory
  700.             if (!dir.isReadable() || !dir.isWritable()) {
  701.                 dir.permissions = 0755;
  702.             }
  703.             return true;
  704.         }
  705.         catch (e) {
  706.             return false;
  707.         }
  708.     },
  709.  
  710.     read: function(dir, recursive) {
  711.         var list = new Array();
  712.         try {
  713.             if (dir.isDirectory()) {
  714.                 if (recursive == null) {
  715.                     recursive = false;
  716.                 }
  717.                 var files = dir.directoryEntries;
  718.                 list = this._read(files, recursive);
  719.             }
  720.         }
  721.         catch (e) {
  722.             // foobar!
  723.         }
  724.         return list;
  725.     },
  726.  
  727.     _read: function(dirEntry, recursive) {
  728.         var list = new Array();
  729.         try {
  730.             while (dirEntry.hasMoreElements()) {
  731.                 list.push(dirEntry.getNext()
  732.                                 .QueryInterface(File.localfileIID));
  733.             }
  734.             if (recursive) {
  735.                 var list2 = new Array();
  736.                 for (var i = 0; i < list.length; ++i) {
  737.                     if (list[i].isDirectory()) {
  738.                         files = list[i].directoryEntries;
  739.                         list2 = this._read(files, recursive);
  740.                     }
  741.                 }
  742.                 for (i = 0; i < list2.length; ++i) {
  743.                     list.push(list2[i]);
  744.                 }
  745.             }
  746.         }
  747.         catch (e) {
  748.             // foobar!
  749.         }
  750.         return list;
  751.     },
  752.  
  753.     unlink: function(dir, recursive) {
  754.         try {
  755.             if (recursive == null) {
  756.                 recursive = false;
  757.             }
  758.             dir.remove(recursive);
  759.             return true;
  760.         }
  761.         catch (e) {
  762.             return false;
  763.         }
  764.     },
  765.  
  766.     path: function(dir) {
  767.         return File.path(dir);
  768.     },
  769.  
  770.     split: function(str, join) {
  771.         var arr = str.split(/\/|\\/), i;
  772.         str = new String();
  773.         for (i = 0; i < arr.length; ++i) {
  774.             str += arr[i] + ((i != arr.length - 1) ?
  775.                                     join : '');
  776.         }
  777.         return str;
  778.     },
  779.  
  780.     join: function(str, split) {
  781.         var arr = str.split(split), i;
  782.         str = new String();
  783.         for (i = 0; i < arr.length; ++i) {
  784.             str += arr[i] + ((i != arr.length - 1) ?
  785.                                     this.sep : '');
  786.         }
  787.         return str;
  788.     }
  789.  
  790. }
  791.  
  792. if ("@mozilla.org/windows-registry-key;1" in Components.classes)
  793.     Dir.sep = "\\";
  794.         
  795. var IOManager =
  796. {
  797.     GetPrefsDir: function() {
  798.         return Dir.get('ProfD');
  799.     },
  800.  
  801.     GetSearchPluginsDir: function() {
  802.         return Dir.get("SrchPlugns");
  803.     },
  804.  
  805.     GetExtentionPath: function(id) {
  806.         var strExtPath = "";
  807.         try {
  808.             var ext = Components.classes["@mozilla.org/extensions/manager;1"]
  809.                     .getService(Components.interfaces.nsIExtensionManager)
  810.                     .getInstallLocation(id)
  811.                     .getItemLocation(id);
  812.             strExtPath = ext.path;
  813.         }
  814.         catch (ex) {
  815.             strExtPath = "";
  816.         }
  817.  
  818.         finally {
  819.             return strExtPath;
  820.         }
  821.     },
  822.  
  823.     CreateDir: function(strDirName) {
  824.         var ebDirPath = this.GetPrefsDir().path + Dir.sep + strDirName;
  825.         var ebDir = Dir.open(ebDirPath);
  826.         if (!ebDir.exists()) {
  827.             Dir.create(ebDir);
  828.         }
  829.         return ebDir;
  830.     },
  831.  
  832.     CreateToolbarFile: function(strFileName, strCTID) {
  833.         var ebFile = null;
  834.         try {
  835.             var ebDir = this.CreateDir(strCTID);
  836.             ebFile = File.open(ebDir.path + Dir.sep + strFileName);
  837.             if (!ebFile.exists()) {
  838.                 File.create(ebFile);
  839.             }
  840.         }
  841.         catch (err) {
  842.             ebFile = null;
  843.         }
  844.         finally {
  845.             return ebFile;
  846.         }
  847.     },
  848.  
  849.     DeleteToolbarDirectory: function(strCTID) {
  850.         var bRetVal = false;
  851.         try {
  852.             var objEBDir = this.CreateDir(strCTID);
  853.             Dir.unlink(objEBDir, true);
  854.             bRetVal = true;
  855.         }
  856.         catch (err) {
  857.             bRetVal = false;
  858.         }
  859.  
  860.         return bRetVal;
  861.     },
  862.  
  863.     IsToolbarFileExists: function(strFileName, strCTID) {
  864.         var bRetVal = false;
  865.         try {
  866.             var ebDir = this.CreateDir(strCTID);
  867.             ebFile = File.open(ebDir.path + Dir.sep + strFileName);
  868.             bRetVal = ebFile.exists();
  869.         }
  870.         catch (err) {
  871.             bRetVal = false;
  872.         }
  873.  
  874.         return bRetVal;
  875.     }
  876. }
  877. if (typeof JSON == "undefined") {
  878.     //FF3.5
  879.     if (AppInfo.isGecko191) {
  880.         //do nothing
  881.     }
  882.     //FF3
  883.     else if (AppInfo.isGecko19) {
  884.         var myJson = Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON);
  885.         JSON = {};
  886.         JSON.stringify = function(obj) { return myJson.encode(obj); };
  887.         JSON.parse = function(str) { return myJson.decode(str); };
  888.     }
  889.     //FF2
  890.     else {
  891.         var myJson = {
  892.             stringify: function(aJSObject, aKeysToDrop) {
  893.                 var pieces = [];
  894.  
  895.                 function append_piece(aObj) {
  896.                     if (typeof aObj == "string") {
  897.                         aObj = aObj.replace(/[\\"\x00-\x1F\u0080-\uFFFF]/g, function($0) {
  898.                             switch ($0) {
  899.                                 case "\b": return "\\b";
  900.                                 case "\t": return "\\t";
  901.                                 case "\n": return "\\n";
  902.                                 case "\f": return "\\f";
  903.                                 case "\r": return "\\r";
  904.                                 case '"': return '\\"';
  905.                                 case "\\": return "\\\\";
  906.                             }
  907.                             return "\\u" + ("0000" + $0.charCodeAt(0).toString(16)).slice(-4);
  908.                         });
  909.                         pieces.push('"' + aObj + '"')
  910.                     }
  911.                     else if (typeof aObj == "boolean") {
  912.                         pieces.push(aObj ? "true" : "false");
  913.                     }
  914.                     else if (typeof aObj == "number" && isFinite(aObj)) {
  915.                         pieces.push(aObj.toString());
  916.                     }
  917.                     else if (aObj === null) {
  918.                         pieces.push("null");
  919.                     }
  920.                     else if (aObj instanceof Array ||
  921.                 typeof aObj == "object" && "length" in aObj &&
  922.                 (aObj.length === 0 || aObj[aObj.length - 1] !== undefined)) {
  923.                         pieces.push("[");
  924.                         for (var i = 0; i < aObj.length; i++) {
  925.                             arguments.callee(aObj[i]);
  926.                             pieces.push(",");
  927.                         }
  928.                         if (aObj.length > 0)
  929.                             pieces.pop(); // drop the trailing colon
  930.                         pieces.push("]");
  931.                     }
  932.                     else if (typeof aObj == "object") {
  933.                         pieces.push("{");
  934.                         for (var key in aObj) {
  935.                             // allow callers to pass objects containing private data which
  936.                             // they don't want the JSON string to contain (so they don't
  937.                             // have to manually pre-process the object)
  938.                             if (aKeysToDrop && aKeysToDrop.indexOf(key) != -1)
  939.                                 continue;
  940.  
  941.                             arguments.callee(key.toString());
  942.                             pieces.push(":");
  943.                             arguments.callee(aObj[key]);
  944.                             pieces.push(",");
  945.                         }
  946.                         if (pieces[pieces.length - 1] == ",")
  947.                             pieces.pop(); // drop the trailing colon
  948.                         pieces.push("}");
  949.                     }
  950.                     else {
  951.                         throw new TypeError("No JSON representation for this object!");
  952.                     }
  953.                 }
  954.                 append_piece(aJSObject);
  955.  
  956.                 return pieces.join("");
  957.             },
  958.  
  959.             /**
  960.             * Converts a JSON string into a JavaScript object.
  961.             *
  962.             * @param aJSONString is the string to be converted
  963.             * @return a JavaScript object for the given JSON representation
  964.             */
  965.             parse: function(aJSONString) {
  966.                 if (!this.isMostlyHarmless(aJSONString))
  967.                     throw new SyntaxError("No valid JSON string!");
  968.  
  969.                 var s = new Components.utils.Sandbox("about:blank");
  970.                 return Components.utils.evalInSandbox("(" + aJSONString + ")", s);
  971.             },
  972.  
  973.             /**
  974.             * Checks whether the given string contains potentially harmful
  975.             * content which might be executed during its evaluation
  976.             * (no parser, thus not 100% safe! Best to use a Sandbox for evaluation)
  977.             *
  978.             * @param aString is the string to be tested
  979.             * @return a boolean
  980.             */
  981.             isMostlyHarmless: function(aString) {
  982.                 var maybeHarmful = /[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/;
  983.                 var jsonStrings = /"(\\.|[^"\\\n\r])*"/g;
  984.  
  985.                 return !maybeHarmful.test(aString.replace(jsonStrings, ""));
  986.             }
  987.         }
  988.         JSON = myJson;
  989.     }
  990. };/**
  991. *
  992. *  MD5 (Message-Digest Algorithm)
  993. *  http://www.webtoolkit.info/
  994. *
  995. **/
  996.  
  997. var MD5 = function(string) {
  998.  
  999.     function RotateLeft(lValue, iShiftBits) {
  1000.         return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
  1001.     }
  1002.  
  1003.     function AddUnsigned(lX, lY) {
  1004.         var lX4, lY4, lX8, lY8, lResult;
  1005.         lX8 = (lX & 0x80000000);
  1006.         lY8 = (lY & 0x80000000);
  1007.         lX4 = (lX & 0x40000000);
  1008.         lY4 = (lY & 0x40000000);
  1009.         lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
  1010.         if (lX4 & lY4) {
  1011.             return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
  1012.         }
  1013.         if (lX4 | lY4) {
  1014.             if (lResult & 0x40000000) {
  1015.                 return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
  1016.             } else {
  1017.                 return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
  1018.             }
  1019.         } else {
  1020.             return (lResult ^ lX8 ^ lY8);
  1021.         }
  1022.     }
  1023.  
  1024.     function F(x, y, z) { return (x & y) | ((~x) & z); }
  1025.     function G(x, y, z) { return (x & z) | (y & (~z)); }
  1026.     function H(x, y, z) { return (x ^ y ^ z); }
  1027.     function I(x, y, z) { return (y ^ (x | (~z))); }
  1028.  
  1029.     function FF(a, b, c, d, x, s, ac) {
  1030.         a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
  1031.         return AddUnsigned(RotateLeft(a, s), b);
  1032.     };
  1033.  
  1034.     function GG(a, b, c, d, x, s, ac) {
  1035.         a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
  1036.         return AddUnsigned(RotateLeft(a, s), b);
  1037.     };
  1038.  
  1039.     function HH(a, b, c, d, x, s, ac) {
  1040.         a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
  1041.         return AddUnsigned(RotateLeft(a, s), b);
  1042.     };
  1043.  
  1044.     function II(a, b, c, d, x, s, ac) {
  1045.         a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
  1046.         return AddUnsigned(RotateLeft(a, s), b);
  1047.     };
  1048.  
  1049.     function ConvertToWordArray(string) {
  1050.         var lWordCount;
  1051.         var lMessageLength = string.length;
  1052.         var lNumberOfWords_temp1 = lMessageLength + 8;
  1053.         var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
  1054.         var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
  1055.         var lWordArray = Array(lNumberOfWords - 1);
  1056.         var lBytePosition = 0;
  1057.         var lByteCount = 0;
  1058.         while (lByteCount < lMessageLength) {
  1059.             lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  1060.             lBytePosition = (lByteCount % 4) * 8;
  1061.             lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
  1062.             lByteCount++;
  1063.         }
  1064.         lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  1065.         lBytePosition = (lByteCount % 4) * 8;
  1066.         lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
  1067.         lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
  1068.         lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
  1069.         return lWordArray;
  1070.     };
  1071.  
  1072.     function WordToHex(lValue) {
  1073.         var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
  1074.         for (lCount = 0; lCount <= 3; lCount++) {
  1075.             lByte = (lValue >>> (lCount * 8)) & 255;
  1076.             WordToHexValue_temp = "0" + lByte.toString(16);
  1077.             WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
  1078.         }
  1079.         return WordToHexValue;
  1080.     };
  1081.  
  1082.     function Utf8Encode(string) {
  1083.         string = string.replace(/\r\n/g, "\n");
  1084.         var utftext = "";
  1085.  
  1086.         for (var n = 0; n < string.length; n++) {
  1087.  
  1088.             var c = string.charCodeAt(n);
  1089.  
  1090.             if (c < 128) {
  1091.                 utftext += String.fromCharCode(c);
  1092.             }
  1093.             else if ((c > 127) && (c < 2048)) {
  1094.                 utftext += String.fromCharCode((c >> 6) | 192);
  1095.                 utftext += String.fromCharCode((c & 63) | 128);
  1096.             }
  1097.             else {
  1098.                 utftext += String.fromCharCode((c >> 12) | 224);
  1099.                 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  1100.                 utftext += String.fromCharCode((c & 63) | 128);
  1101.             }
  1102.  
  1103.         }
  1104.  
  1105.         return utftext;
  1106.     };
  1107.  
  1108.     var x = Array();
  1109.     var k, AA, BB, CC, DD, a, b, c, d;
  1110.     var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
  1111.     var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
  1112.     var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
  1113.     var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
  1114.  
  1115.     string = Utf8Encode(string);
  1116.  
  1117.     x = ConvertToWordArray(string);
  1118.  
  1119.     a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
  1120.  
  1121.     for (k = 0; k < x.length; k += 16) {
  1122.         AA = a; BB = b; CC = c; DD = d;
  1123.         a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
  1124.         d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
  1125.         c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
  1126.         b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
  1127.         a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
  1128.         d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
  1129.         c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
  1130.         b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
  1131.         a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
  1132.         d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
  1133.         c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
  1134.         b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
  1135.         a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
  1136.         d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
  1137.         c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
  1138.         b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
  1139.         a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
  1140.         d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
  1141.         c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
  1142.         b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
  1143.         a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
  1144.         d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
  1145.         c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
  1146.         b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
  1147.         a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
  1148.         d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
  1149.         c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
  1150.         b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
  1151.         a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
  1152.         d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
  1153.         c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
  1154.         b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
  1155.         a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
  1156.         d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
  1157.         c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
  1158.         b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
  1159.         a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
  1160.         d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
  1161.         c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
  1162.         b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
  1163.         a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
  1164.         d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
  1165.         c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
  1166.         b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
  1167.         a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
  1168.         d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
  1169.         c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
  1170.         b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
  1171.         a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
  1172.         d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
  1173.         c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
  1174.         b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
  1175.         a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
  1176.         d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
  1177.         c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
  1178.         b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
  1179.         a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
  1180.         d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
  1181.         c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
  1182.         b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
  1183.         a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
  1184.         d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
  1185.         c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
  1186.         b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
  1187.         a = AddUnsigned(a, AA);
  1188.         b = AddUnsigned(b, BB);
  1189.         c = AddUnsigned(c, CC);
  1190.         d = AddUnsigned(d, DD);
  1191.     }
  1192.  
  1193.     var temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d);
  1194.  
  1195.     return temp.toLowerCase();
  1196. };
  1197. function BaseObserver() {
  1198.     this.Topic = "";
  1199.     var NSIObserverService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces["nsIObserverService"]);
  1200.  
  1201.     this.register = function() {
  1202.         NSIObserverService.addObserver(this, this.Topic, false);
  1203.     };
  1204.  
  1205.     this.unregister = function() {
  1206.         NSIObserverService.removeObserver(this, this.Topic);
  1207.     };
  1208.  
  1209.     this.observe = function(aSubject, aTopic, aData) {
  1210.         //Implement in inherited class
  1211.     };
  1212. };
  1213.  
  1214. //Preferences manager object definition
  1215. function PrefManager(strOriginalCTID, strCurrentCTID) {
  1216.     this.prefPrefix = "";
  1217.     this.prefMCPrefix = "";
  1218.  
  1219.     this.init = function(strOriginalCTID, strCurrentCTID) {
  1220.         this.prefPrefix = strOriginalCTID + ".";
  1221.         if (strOriginalCTID != strCurrentCTID)
  1222.             this.prefMCPrefix = this.prefPrefix + strCurrentCTID + ".";
  1223.         else
  1224.             this.prefMCPrefix = this.prefPrefix;
  1225.     };
  1226.  
  1227.     this.GetPrefixPrefName = function(isMC) {
  1228.         if (typeof isMC == "undefined") isMC = false;
  1229.  
  1230.         return (isMC) ? this.prefMCPrefix : this.prefPrefix;
  1231.     };
  1232.  
  1233.     this.GetPref = function(strName, isMC, defaultValue) {
  1234.         var strPrefixPrefName = this.GetPrefixPrefName(isMC);
  1235.         var strFullPrefName = strPrefixPrefName + strName;
  1236.         if (typeof defaultValue == "undefined")
  1237.             return PrefService.GetPref(strFullPrefName);
  1238.         else
  1239.             return (PrefService.HasUserValue(strFullPrefName)) ? PrefService.GetPref(strFullPrefName) : defaultValue;
  1240.     };
  1241.  
  1242.     this.SetPref = function(strName, strValue, isMC) {
  1243.         var strPrefixPrefName = this.GetPrefixPrefName(isMC);
  1244.         var strFullPrefName = strPrefixPrefName + strName;
  1245.         PrefService.SetPref(strFullPrefName, strValue);
  1246.     };
  1247.  
  1248.     this.HasUserValue = function(strName, isMC) {
  1249.         var strPrefixPrefName = this.GetPrefixPrefName(isMC);
  1250.         var strFullPrefName = strPrefixPrefName + strName;
  1251.         return PrefService.HasUserValue(strFullPrefName);
  1252.     };
  1253.  
  1254.     this.Clear = function(strName, isMC) {
  1255.         var strPrefixPrefName = this.GetPrefixPrefName(isMC);
  1256.         var strFullPrefName = strPrefixPrefName + strName;
  1257.         PrefService.ClearUserValue(strFullPrefName);
  1258.     };
  1259.     
  1260.     this.ClearAll = function() {
  1261.         PrefService.DeleteBranch(this.originalCTID);
  1262.     };
  1263.  
  1264.     this.init(strOriginalCTID, strCurrentCTID);
  1265. }
  1266. //interface to write/read from the prefrence file(about:config) - 
  1267. //the registry of firefox
  1268. var PrefService =
  1269. {
  1270.     PREFERENCE_SERVICE: Components.classes["@mozilla.org/preferences-service;1"].
  1271.                 getService(Components.interfaces.nsIPrefBranch),
  1272.  
  1273.     GetPref: function(strName) {
  1274.         var strRetVal;
  1275.         try {
  1276.             switch (this.PREFERENCE_SERVICE.getPrefType(strName)) {
  1277.                 case this.PREFERENCE_SERVICE.PREF_BOOL:
  1278.                     strRetVal = this.PREFERENCE_SERVICE.getBoolPref(strName);
  1279.                     break;
  1280.                 case this.PREFERENCE_SERVICE.PREF_INT:
  1281.                     strRetVal = this.PREFERENCE_SERVICE.getIntPref(strName);
  1282.                     break;
  1283.                 case this.PREFERENCE_SERVICE.PREF_STRING:
  1284.                     strRetVal = this.PREFERENCE_SERVICE.getCharPref(strName);
  1285.                     break;
  1286.                 default:
  1287.                     strRetVal = null;
  1288.                     break;
  1289.             }
  1290.             return strRetVal;
  1291.         }
  1292.         catch (e) {
  1293.             return null;
  1294.         }
  1295.     },
  1296.  
  1297.     SetPref: function(strName, strValue) {
  1298.         if (this.HasUserValue(strName))
  1299.             this.ClearUserValue(strName);
  1300.             
  1301.         if (strValue == null) {
  1302.             this.SetPref(strName, "");
  1303.             this.PREFERENCE_SERVICE.clearUserPref(strName);
  1304.             return true;
  1305.         }
  1306.         
  1307.         try {
  1308.             switch (typeof strValue) {
  1309.                 case 'boolean':
  1310.                     this.PREFERENCE_SERVICE.setBoolPref(strName, strValue);
  1311.                     break;
  1312.                 case 'number':
  1313.                     this.PREFERENCE_SERVICE.setIntPref(strName, strValue);
  1314.                     break;
  1315.                 case 'string':
  1316.                     this.PREFERENCE_SERVICE.setCharPref(strName, strValue);
  1317.                     break;
  1318.                 default:
  1319.                     try {
  1320.                         var str = strValue.toString();
  1321.                         this.PREFERENCE_SERVICE.setCharPref(strName, str);
  1322.                     } catch (e) {
  1323.                         return false;
  1324.                     }
  1325.                     break;
  1326.             }
  1327.         }
  1328.         catch (ex) {
  1329.             Logging.LogToConsole("Set prefs error\nPref Name: " + strName + "\nValue: " + strValue + "\nException: " + ex);
  1330.         }
  1331.         return true;
  1332.     },
  1333.  
  1334.     HasUserValue: function(strName) {
  1335.         return this.PREFERENCE_SERVICE.prefHasUserValue(strName);
  1336.     },
  1337.  
  1338.     ClearUserValue: function(strName) {
  1339.         this.PREFERENCE_SERVICE.clearUserPref(strName);
  1340.     },
  1341.  
  1342.     DeleteBranch: function(strBranchName) {
  1343.         this.PREFERENCE_SERVICE.deleteBranch(strBranchName);
  1344.     }
  1345.  
  1346. }
  1347.  
  1348. var GlobalPrefs =
  1349. {
  1350.     GetPrefixPrefName: function() {
  1351.         var strPrefixPrefName = "CommunityToolbar.";
  1352.         return strPrefixPrefName;
  1353.     },
  1354.  
  1355.     GetPref: function(strName) {
  1356.         var strPrefixPrefName = this.GetPrefixPrefName();
  1357.  
  1358.         var strFullPrefName = strPrefixPrefName + strName;
  1359.  
  1360.         return PrefService.GetPref(strFullPrefName);
  1361.     },
  1362.  
  1363.     SetPref: function(strName, strValue) {
  1364.         var strPrefixPrefName = this.GetPrefixPrefName();
  1365.  
  1366.         var strFullPrefName = strPrefixPrefName + strName;
  1367.         PrefService.SetPref(strFullPrefName, strValue);
  1368.     },
  1369.  
  1370.     HasUserValue: function(strName) {
  1371.         var strPrefixPrefName = this.GetPrefixPrefName();
  1372.  
  1373.         var strFullPrefName = strPrefixPrefName + strName;
  1374.         return PrefService.HasUserValue(strFullPrefName);
  1375.     },
  1376.  
  1377.     ClearAll: function() {
  1378.         PrefService.DeleteBranch(this.GetPrefixPrefName());
  1379.     }
  1380. }
  1381. var ToolbarPrefsConsts =
  1382. {
  1383.     InstalledDate: "InstalledDate",
  1384.     EnableUsage: "EnableUsage"
  1385. };
  1386.  
  1387. var EBServerDataURL =
  1388. {
  1389.     ServiceRequest: function(objRequestData) {
  1390.         this.HTTPServerRequest(objRequestData.url, objRequestData.postParams, false, objRequestData.callback, objRequestData.state, false);
  1391.     },
  1392.  
  1393.     HTTPServerRequest: function(strURL, strPostParams, bIsResponseXML, oCallBackFunction, state, bIgnoreStatus) {
  1394.         if (typeof bIgnoreStatus == "undefined") bIgnoreStatus = false;
  1395.         var oResponseData = null;
  1396.         var strNetworkError = "EB_NETWORK_ERROR";
  1397.         var oRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Components.interfaces.nsIXMLHttpRequest);
  1398.         oRequest.mozBackgroundRequest = true;
  1399.         var strMethod = strPostParams ? 'POST' : 'GET';
  1400.  
  1401.         oRequest.open(strMethod, strURL, true);
  1402.  
  1403.         oRequest.onreadystatechange = function() {
  1404.             //create an object that represent if there was a network error
  1405.             var o = new Object();
  1406.             o.value = '';
  1407.             var bComplete = false;
  1408.             try {
  1409.                 if (oRequest.readyState == 4 && (oRequest.status == 200 || bIgnoreStatus)) {
  1410.                     bComplete = true;
  1411.                     if (bIsResponseXML) {
  1412.                         oResponseData = oRequest.responseXML;
  1413.                     }
  1414.                     else {
  1415.                         oResponseData = oRequest.responseText;
  1416.                     }
  1417.                 }
  1418.             }
  1419.             catch (ex) {
  1420.                 oResponseData = null;
  1421.                 o.value = strNetworkError;
  1422.                 bComplete = true;
  1423.             }
  1424.  
  1425.             if (bComplete) {
  1426.                 if (oCallBackFunction) {
  1427.                     oCallBackFunction(oResponseData, o, state);
  1428.                 }
  1429.             }
  1430.         };
  1431.  
  1432.         oRequest.setRequestHeader('PRAGMA', 'NO-CACHE');
  1433.         oRequest.setRequestHeader('CACHE-CONTROL', 'NO-CACHE');
  1434.  
  1435.         if (strPostParams) {
  1436.             oRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  1437.         }
  1438.         oRequest.send(strPostParams);
  1439.  
  1440.         //return the request object
  1441.         return oRequest;
  1442.     },
  1443.  
  1444.     ServerRequest: function(strURL, strPostData, strUserName, strPassword, ServerResponseFunction) {
  1445.         var objIOService = Components.classes["@mozilla.org/network/io-service;1"].createInstance(Components.interfaces.nsIIOService);
  1446.         var objURI = objIOService.newURI(strURL, null, null);
  1447.  
  1448.         if (strUserName != null && strPassword != null) {
  1449.             objURI.username = strUserName;
  1450.             objURI.password = strPassword;
  1451.         }
  1452.  
  1453.         var objChannel = objIOService.newChannelFromURI(objURI);
  1454.  
  1455.         objChannel.QueryInterface(Components.interfaces.nsIHttpChannel).setRequestHeader('PRAGMA', 'NO-CACHE', false);
  1456.         objChannel.QueryInterface(Components.interfaces.nsIHttpChannel).setRequestHeader('CACHE-CONTROL', 'NO-CACHE', false);
  1457.  
  1458.  
  1459.         if (strPostData != null) {
  1460.             var objUploadStream = Components.classes["@mozilla.org/io/string-input-stream;1"].createInstance(Components.interfaces.nsIStringInputStream);
  1461.             objUploadStream.setData(strPostData, strPostData.length);
  1462.  
  1463.             var objUploadChannel = objChannel.QueryInterface(Components.interfaces.nsIUploadChannel);
  1464.             objUploadChannel.setUploadStream(objUploadStream, "application/x-www-form-urlencoded", -1);
  1465.  
  1466.             objChannel.QueryInterface(Components.interfaces.nsIHttpChannel).requestMethod = "POST";
  1467.         }
  1468.  
  1469.         var objObserver = new this.Observer(ServerResponseFunction);
  1470.         objChannel.asyncOpen(objObserver, null);
  1471.     },
  1472.  
  1473.     Observer: function(ServerResponseFunction) {
  1474.         return ({
  1475.             Data: "",
  1476.  
  1477.             onStartRequest: function(aRequest, aContext) {
  1478.                 this.Data = "";
  1479.             },
  1480.  
  1481.             onStopRequest: function(aRequest, aContext, aStatus) {
  1482.                 if (ServerResponseFunction) {
  1483.                     ServerResponseFunction(this.Data, aRequest);
  1484.                 }
  1485.             },
  1486.  
  1487.             onDataAvailable: function(aRequest, aContext, aStream, aSourceOffset, aLength) {
  1488.                 var objScriptableInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  1489.                 objScriptableInputStream.init(aStream);
  1490.                 this.Data += objScriptableInputStream.read(aLength);
  1491.             }
  1492.         });
  1493.     }
  1494. }
  1495.  
  1496. function BaseServerRequest() {
  1497.     this.callback = null;
  1498.     this.url = "";
  1499.     this.postParams = "";
  1500. };
  1501. var ToolbarFunctions =
  1502. {
  1503.     getToolbarAgeInDays: function(oPrefs) {
  1504.         var stringToTimestamp = function(strServerDate) {
  1505.             if (!strServerDate) return null;
  1506.             
  1507.             var arrDate = strServerDate.split("-");
  1508.             if (arrDate.length != 3) return null;
  1509.             
  1510.             var oDate = new Date();
  1511.             oDate.setDate(arrDate[0]);
  1512.             oDate.setMonth(parseInt(arrDate[1]) - 1);
  1513.             oDate.setFullYear(arrDate[2]);
  1514.             
  1515.             var iTimestamp = Date.parse(oDate.toDateString());
  1516.             return isNaN(iTimestamp) ? null : iTimestamp;
  1517.         };
  1518.  
  1519.         var strCreatedDate = oPrefs.GetPref(LoginPrefConsts.FirstServerDate);
  1520.         var iCreatedDate = stringToTimestamp(strCreatedDate);
  1521.         if (!iCreatedDate) return -1;
  1522.  
  1523.         var strCurrentDate = oPrefs.GetPref(LoginPrefConsts.CurrentServerDate);
  1524.         var iCurrentDate = stringToTimestamp(strCurrentDate);
  1525.         if (!iCurrentDate) return -1;
  1526.  
  1527.         var iMilliseconds = iCurrentDate - iCreatedDate;
  1528.         var iDays = parseInt(iMilliseconds / (1000 * 60 * 60 * 24));
  1529.         return (isNaN(iDays)) ? -1 : iDays;
  1530.     }
  1531. };
  1532.  
  1533. var URL =
  1534. {
  1535.     HTTPS_PROTOCOL: "https://",
  1536.     HTTP_PROTOCOL: "http://",
  1537.     BookmarkletPrefix: 'javascript:',
  1538.  
  1539.     BeginsWith: function(str, pref) {
  1540.         return str.substring(0, pref.length).toUpperCase() == pref.toUpperCase();
  1541.     },
  1542.  
  1543.     IsBookmarklet: function(strUrl) {
  1544.         var strBookmarkletPrefix = this.BookmarkletPrefix;
  1545.         return this.BeginsWith(strUrl, strBookmarkletPrefix);
  1546.     },
  1547.  
  1548.     AddHTTPProtocol: function(strUrl) {
  1549.         var firstDot = strUrl.indexOf('.');
  1550.         var firstColum = strUrl.indexOf(':');
  1551.         if ((firstDot < firstColum && firstDot != -1) || firstColum == -1 && strUrl)
  1552.             strUrl = this.HTTP_PROTOCOL + strUrl;
  1553.  
  1554.         return strUrl;
  1555.     },
  1556.  
  1557.     GetProtocol: function(strUrl) {
  1558.         var arrMatches = strUrl.match(/(.*?):\/\//);
  1559.         if (arrMatches == null || arrMatches.length < 1) return "";
  1560.  
  1561.         return arrMatches[0];
  1562.     },
  1563.  
  1564.     LegalizeLinkUrl: function(strLinkUrl) {
  1565.         if (this.IsBookmarklet(strLinkUrl))
  1566.             strLinkUrl = this.LegalizeBoolmarkletURL(strLinkUrl);
  1567.         else {
  1568.             strLinkUrl = strLinkUrl.replace(/\\/g, "\\\\");
  1569.             strLinkUrl = strLinkUrl.replace(/'/g, "\'");
  1570.             strLinkUrl = this.AddHTTPProtocol(strLinkUrl);
  1571.         }
  1572.         return strLinkUrl;
  1573.     },
  1574.  
  1575.     LegalizeBoolmarkletURL: function(strURL) {
  1576.         var strBookmarkletPrefix = this.BookmarkletPrefix;
  1577.         if (this.BeginsWith(strURL, strBookmarkletPrefix))
  1578.             strURL = XML.FromLegalXml(strURL);
  1579.  
  1580.         return strURL;
  1581.     },
  1582.  
  1583.     //cehck validation of url if it starts with http:// or https:// or ftp://
  1584.     //and there is characters after it
  1585.     IsLegalURL: function(strURL) {
  1586.         var strRegex = /^(http:\/\/|https:\/\/|ftp:\/\/).+/i;
  1587.         return strRegex.test(strURL);
  1588.     },
  1589.  
  1590.     IsValidURL: function(strURL) {
  1591.         if (strURL.indexOf('.') == -1)
  1592.             return false;
  1593.  
  1594.         if (strURL.charAt(0) == '@')
  1595.             return false;
  1596.  
  1597.         return true;
  1598.     },
  1599.  
  1600.     GetBaseUrl: function(strURL) {
  1601.         //get the protocol in the first cell in the array - 
  1602.         //and the url (till the querystring) in the second cell of the array
  1603.         var arrMatches = strURL.match(/^(http:\/\/|https:\/\/|ftp:\/\/)?([^\/^\?^:]+)/i);
  1604.         var strProtocol = '';
  1605.         var strBaseUrl = '';
  1606.  
  1607.         if (arrMatches) {
  1608.             strProtocol = arrMatches[1];
  1609.             strBaseUrl = arrMatches[2];
  1610.  
  1611.             if (strProtocol) {
  1612.                 strBaseUrl = strProtocol + strBaseUrl;
  1613.             }
  1614.         }
  1615.  
  1616.         if (!strBaseUrl) {
  1617.             strBaseUrl = strURL;
  1618.         }
  1619.  
  1620.         return strBaseUrl;
  1621.     },
  1622.  
  1623.     GetBaseUrlWithoutProtocol: function(strURL) {
  1624.         //get the protocol in the first cell in the array - 
  1625.         //and the url (till the querystring) in the second cell of the array
  1626.         var arrMatches = strURL.match(/^(http:\/\/|https:\/\/|ftp:\/\/)?([^\/^\?^:]+)/i);
  1627.         var strProtocol = '';
  1628.         var strBaseUrl = '';
  1629.  
  1630.         if (arrMatches) {
  1631.             strProtocol = arrMatches[1];
  1632.             strBaseUrl = arrMatches[2];
  1633.         }
  1634.  
  1635.         if (!strBaseUrl)
  1636.             strBaseUrl = strURL;
  1637.  
  1638.         return strBaseUrl;
  1639.     },
  1640.  
  1641.     GetTopLevelDomainName: function(strUrl, bIsWithExtension) {
  1642.         var strExtension = '';
  1643.         var strBaseUrl = this.GetBaseUrl(strUrl);
  1644.         strBaseUrl = strBaseUrl.replace(this.HTTP_PROTOCOL, "");
  1645.         var iLast = strBaseUrl.lastIndexOf(".");
  1646.         strExtension = strBaseUrl.substring(iLast);
  1647.         strBaseUrl = strBaseUrl.substring(0, iLast);
  1648.         iLast = strBaseUrl.lastIndexOf(".");
  1649.  
  1650.         var strPotential = strBaseUrl.substring(iLast + 1);
  1651.  
  1652.         if (strPotential != "com" && strPotential != "co" && strPotential != "org" && strPotential != "gov" && strPotential != "net")
  1653.             strBaseUrl = strPotential;
  1654.         else {
  1655.             strExtension = strPotential + '.' + strExtension;
  1656.             iLast = strBaseUrl.lastIndexOf(".");
  1657.             strBaseUrl = strBaseUrl.substring(0, iLast);
  1658.             iLast = strBaseUrl.lastIndexOf(".");
  1659.             strBaseUrl = strBaseUrl.substring(iLast + 1);
  1660.  
  1661.             if (!strBaseUrl)
  1662.                 strBaseUrl = strPotential;
  1663.         }
  1664.  
  1665.         if (bIsWithExtension)
  1666.             return strBaseUrl + strExtension;
  1667.         else
  1668.             return strBaseUrl;
  1669.     },
  1670.  
  1671.     GetSubDomain: function(strUrl) {
  1672.         var strSubDomain = "";
  1673.         try {
  1674.             strUrl = strUrl.replace(/http:\/\//, '');
  1675.             var iEnd = strUrl.indexOf('.');
  1676.             strSubDomain = strUrl.substr(0, iEnd);
  1677.         }
  1678.         catch (e) { }
  1679.  
  1680.         return strSubDomain;
  1681.     },
  1682.  
  1683.     GetPageUrl: function() {
  1684.         var window = getWindow();
  1685.         var strUrl = "";
  1686.         if (typeof window.gBrowser != "undefined")
  1687.             strUrl = window.gBrowser.contentDocument.location.href;
  1688.  
  1689.         return strUrl;
  1690.     },
  1691.  
  1692.     IsSecuredUrl: function() {
  1693.         var strUrl = this.GetPageUrl();
  1694.         var strProtocol = this.GetProtocol(strUrl);
  1695.         return (strProtocol.toLowerCase() == this.HTTPS_PROTOCOL);
  1696.     },
  1697.  
  1698.     IsEqualTopLevelDomain: function(url1, url2) {
  1699.         url1 = this.GetTopLevelDomainName(url1, false);
  1700.         url2 = this.GetTopLevelDomainName(url2, false);
  1701.  
  1702.         return (url1.toLowerCase() == url2.toLowerCase());
  1703.     }
  1704. };
  1705. function getWindow() {
  1706.     var objWindowsManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
  1707.                     .getService(Components.interfaces.nsIWindowMediator);
  1708.  
  1709.     var objRecentBrowserWindow = objWindowsManager.getMostRecentWindow('navigator:browser');
  1710.     return objRecentBrowserWindow;
  1711. };
  1712.  
  1713. function getWindows() {
  1714.     var arrWindows = new Array();
  1715.     var objWindowsManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
  1716.                     .getService(Components.interfaces.nsIWindowMediator);
  1717.  
  1718.     var objEnumerator = objWindowsManager.getEnumerator('navigator:browser');
  1719.     var objWindow = null;
  1720.     while (objEnumerator.hasMoreElements()) {
  1721.         objWindow = objEnumerator.getNext();
  1722.         arrWindows.push(objWindow);
  1723.     }
  1724.  
  1725.     return arrWindows;
  1726. };
  1727.  
  1728. function alert(strAlert) {
  1729.     var oWindow = getWindow();
  1730.     if (oWindow) oWindow.alert(strAlert);
  1731. };
  1732.  
  1733. function setTimeout(objCallback, iTimeout) {
  1734.     var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
  1735.     var timerCallback = function() {
  1736.         this.notify = function(timer) {
  1737.             objCallback();
  1738.         };
  1739.     };
  1740.  
  1741.     timer.initWithCallback(new timerCallback(), iTimeout, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  1742.     return timer;
  1743. };
  1744.  
  1745. function setInterval(objCallback, iTimeout) {
  1746.     var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
  1747.     
  1748.     var timerCallback = function() {
  1749.         this.notify = function(timer) {
  1750.             objCallback();
  1751.         };
  1752.     };
  1753.  
  1754.     timer.initWithCallback(new timerCallback(), iTimeout, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  1755.     return timer;
  1756. };
  1757.  
  1758. function clearTimeout(oTimer) {
  1759.     if (oTimer) oTimer.cancel();
  1760. };
  1761.  
  1762. function clearInterval(oTimer) {
  1763.     if(oTimer) oTimer.cancel();
  1764. };
  1765.  
  1766. function notifyObservers(aSubject, strTopic, oData) {
  1767.     var srvcObservers = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces["nsIObserverService"]);
  1768.     srvcObservers.notifyObservers(aSubject, strTopic, oData);
  1769. };
  1770.  
  1771. stringFormat = function(strText) {
  1772.     if (arguments.length <= 1) return strText;
  1773.     var replaceString = "";
  1774.     for (var i = 0; i < arguments.length - 1; i++) {
  1775.         replaceString = "{" + i.toString() + "}";
  1776.         strText = strText.replace(replaceString, arguments[i + 1]);
  1777.     }
  1778.  
  1779.     return strText;
  1780. };
  1781.  
  1782. function generateGuid() {
  1783.     var uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"].getService(Components.interfaces.nsIUUIDGenerator);
  1784.     var uuid = uuidGenerator.generateUUID();
  1785.     return  uuid.toString();
  1786. };
  1787.  
  1788. function getURI(strUrl) {
  1789.     var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  1790.     return ioService.newURI(strUrl, null, null);
  1791. };
  1792.  
  1793. function getXulWindowByTypeAndName(strWindowType, strWindowName) {
  1794.     var oWindowsManager = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  1795.                     .getService(Components.interfaces.nsIWindowMediator);
  1796.  
  1797.     var oEnumerator = oWindowsManager.getEnumerator(strWindowType);
  1798.  
  1799.     while (oEnumerator.hasMoreElements()) {
  1800.         var oWindow = oEnumerator.getNext();
  1801.  
  1802.         if (oWindow.name == strWindowName)
  1803.             return oWindow;
  1804.     }
  1805.  
  1806.     return null;
  1807. };
  1808.  
  1809. function compareVersions(strVer1, strVer2) {
  1810.     var oVersionCompare = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
  1811.                                         .createInstance(Components.interfaces.nsIVersionComparator);
  1812.     return oVersionCompare.compare(strVer1, strVer2);
  1813. };
  1814.  
  1815. function parseBool(strBool) {
  1816.     if (!strBool) return false;
  1817.     return strBool.toLowerCase() == "true";
  1818. }
  1819.  
  1820. function parseFeaturedBool(strValue, defaultBoolValue) {
  1821.     if (!strValue) return defaultBoolValue;
  1822.  
  1823.     strValue = strValue.toLowerCase();
  1824.     switch (strValue) {
  1825.         case "yes":
  1826.         case "true":
  1827.         case "1": return true;
  1828.         case "no":
  1829.         case "false":
  1830.         case "0": return false;
  1831.         default: return defaultBoolValue;
  1832.     }
  1833. };
  1834.  
  1835. function getJSObjectFromWindow(oContentWindow) {
  1836.     var oJavascript = null;
  1837.  
  1838.     try {
  1839.         if (oContentWindow)
  1840.             oJavascript = oContentWindow.wrappedJSObject ? oContentWindow.wrappedJSObject : oContentWindow;
  1841.     }
  1842.     catch (ex) {
  1843.         EBLog(ex);
  1844.     }
  1845.  
  1846.     return oJavascript;
  1847. };
  1848. //registry manager:
  1849. var RegistryManager =
  1850. {
  1851.     HKEY_CLASSES_ROOT: 0,
  1852.     HKEY_CURRENT_CONFIG: 1,
  1853.     HKEY_CURRENT_USER: 2,
  1854.     HKEY_LOCAL_MACHINE: 3,
  1855.     HKEY_USERS: 4,
  1856.  
  1857.     GetRegistryEntry: function(regRoot, regPath, regName) {
  1858.         if ("@mozilla.org/windows-registry-key;1" in Components.classes) {
  1859.             // This works in Firefox 1.5
  1860.             var nsIWindowsRegKey = Components.classes["@mozilla.org/windows-registry-key;1"].getService(Components.interfaces.nsIWindowsRegKey);
  1861.             var regRootKey = new Array(0x80000000, 0x80000005, 0x80000001, 0x80000002, 0x80000003);
  1862.             nsIWindowsRegKey.open(regRootKey[regRoot], regPath, Components.interfaces.nsIWindowsRegKey.ACCESS_READ);
  1863.  
  1864.             var val = null;
  1865.             if (nsIWindowsRegKey.valueCount) {
  1866.                 switch (nsIWindowsRegKey.getValueType(regName)) {
  1867.                     case nsIWindowsRegKey.TYPE_STRING:
  1868.                         try {
  1869.                             val = nsIWindowsRegKey.readStringValue(regName);
  1870.                         }
  1871.                         catch (ex) {
  1872.                             val = nsIWindowsRegKey.readBinaryValue(regName);
  1873.                         }
  1874.                         break;
  1875.                     case wnsIWindowsRegKeyrk.TYPE_BINARY:
  1876.                         val = nsIWindowsRegKey.readBinaryValue(regName);
  1877.                         break;
  1878.                     case nsIWindowsRegKey.TYPE_INT:
  1879.                         val = nsIWindowsRegKey.readIntValue(regName);
  1880.                         break;
  1881.                     case nsIWindowsRegKey.TYPE_INT64:
  1882.                         val = nsIWindowsRegKey.readInt64Value(regName);
  1883.                         break;
  1884.                 }
  1885.             }
  1886.             nsIWindowsRegKey.close();
  1887.  
  1888.             return val;
  1889.         }
  1890.         else if ("@mozilla.org/browser/shell-service;1" in Components.classes) {
  1891.             // This works in Firefox 1.0.x
  1892.             var nsIWindowsShellService = Components.classes["@mozilla.org/browser/shell-service;1"].getService(Components.interfaces.nsIWindowsShellService);
  1893.  
  1894.             if (nsIWindowsShellService.getRegistryEntry) {
  1895.                 return nsIWindowsShellService.getRegistryEntry(regRoot, regPath, regName);
  1896.             }
  1897.         }
  1898.         else if ("@mozilla.org/winhooks;1" in Components.classes) {
  1899.             // This works in Mozilla 1.7.x
  1900.             var nsIWindowsRegistry = Components.classes["@mozilla.org/winhooks;1"].getService(Components.interfaces.nsIWindowsRegistry);
  1901.             if (nsIWindowsRegistry.getRegistryEntry) {
  1902.                 return nsIWindowsRegistry.getRegistryEntry(regRoot, regPath, regName);
  1903.             }
  1904.         }
  1905.  
  1906.         return null;
  1907.     },
  1908.  
  1909.     WriteRegistryEntry: function(regRoot, regPath, regName, regValue) {
  1910.         if ("@mozilla.org/windows-registry-key;1" in Components.classes) {
  1911.             // This works in Firefox 1.5
  1912.             var nsIWindowsRegKey = Components.classes["@mozilla.org/windows-registry-key;1"].getService(Components.interfaces.nsIWindowsRegKey);
  1913.             var regRootKey = new Array(0x80000000, 0x80000005, 0x80000001, 0x80000002, 0x80000003);
  1914.             nsIWindowsRegKey.create(regRootKey[regRoot], regPath, Components.interfaces.nsIWindowsRegKey.ACCESS_WRITE);
  1915.             nsIWindowsRegKey.writeStringValue(regName, regValue);
  1916.         }
  1917.  
  1918.         return null;
  1919.     }
  1920. };
  1921. var E4X = XML;
  1922. var XML =
  1923. {
  1924.     LegalizeEBXML: function(strXml) {
  1925.         if (!strXml)
  1926.             return;
  1927.  
  1928.         strXml = strXml.replace(/&/g, '&');
  1929.         strXml = strXml.replace(/'/g, '\'');
  1930.  
  1931.         strXml = strXml.replace(/&/g, "&");
  1932.         strXml = strXml.replace(/\'/g, "'");
  1933.  
  1934.         return strXml;
  1935.     },
  1936.  
  1937.     FromLegalXml: function(strXml) {
  1938.         strXml = strXml.replace(/&/g, '&');
  1939.         strXml = strXml.replace(/</g, '<');
  1940.         strXml = strXml.replace(/>/g, '>');
  1941.         strXml = strXml.replace(/"/g, '\"');
  1942.         strXml = strXml.replace(/'/g, '\'');
  1943.         strXml = strXml.replace(/'/g, '\'');
  1944.         strXml = strXml.replace(/'/g, '\'');
  1945.         strXml = strXml.replace(/!/g, '!');
  1946.         strXml = strXml.replace(/!/g, '!');
  1947.         strXml = strXml.replace(/Ü/g, '∩óÉ');
  1948.         strXml = strXml.replace(/Ü/g, '∩óÉ');
  1949.         strXml = strXml.replace(/Ö/g, 'â•«â–“');
  1950.         strXml = strXml.replace(/Ö/g, 'â•«â–“');
  1951.         return strXml;
  1952.     },
  1953.  
  1954.     ToLegalXML: function(strXML) {
  1955.         if (!strXML)
  1956.             return strXML;
  1957.  
  1958.         strXML = strXML.replace(/&/g, '&');
  1959.         strXML = strXML.replace(/</g, '<');
  1960.         strXML = strXML.replace(/>/g, '>');
  1961.         strXML = strXML.replace(/\'/g, ''');
  1962.         strXML = strXML.replace(/\"/g, '"');
  1963.  
  1964.         return strXML;
  1965.     },
  1966.  
  1967.     FixParserError: function(strXml) {
  1968.         strXml = strXml.replace(/'/g, "'");
  1969.         strXml = strXml.replace(/&/g, "&");
  1970.         strXml = strXml.replace(/&/g, "&");
  1971.         strXml = strXml.replace(/'/g, "'");
  1972.         return strXml;
  1973.     },
  1974.  
  1975.     IsLegal: function(xmlDoc) {
  1976.         if (!xmlDoc) return false;
  1977.         if (xmlDoc.documentElement.tagName == "parsererror") return false;
  1978.  
  1979.         return true;
  1980.     },
  1981.  
  1982.     GetXmlDocument: function(strXml) {
  1983.         if (!strXml) return null;
  1984.  
  1985.         var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
  1986.         var objXml = null;
  1987.         try {
  1988.             objXml = parser.parseFromString(strXml, "text/xml");
  1989.             if (objXml && objXml.documentElement.tagName == "parsererror") {
  1990.                 strXml = this.FixParserError(strXml);
  1991.                 objXml = parser.parseFromString(strXml, "text/xml");
  1992.             }
  1993.         }
  1994.         catch (e) {
  1995.         }
  1996.  
  1997.         return objXml;
  1998.     },
  1999.  
  2000.     GetXmlDocumentFromUrl: function(strUrl) {
  2001.  
  2002.         try {
  2003.             var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Components.interfaces.nsIXMLHttpRequest);
  2004.             req.open('GET', strUrl, false);
  2005.             req.send(null);
  2006.             if (req.status == 200 || req.status == 0) {
  2007.                 if (req.responseXML)
  2008.                     return req.responseXML;
  2009.                 else
  2010.                     return this.GetXmlDocument(req.responseText);
  2011.             }
  2012.             else
  2013.                 return null;
  2014.  
  2015.         } catch (e) {
  2016.             return null;
  2017.         }
  2018.     },
  2019.  
  2020.     GetStringXml: function(xmlNode) {
  2021.         var serializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Components.interfaces.nsIDOMSerializer);
  2022.         return serializer.serializeToString(xmlNode);
  2023.     },
  2024.  
  2025.     CreateXmlTextNode: function(xmlDoc, strTagName, strValue) {
  2026.         var XML_NODE = xmlDoc.createElement(strTagName);
  2027.         var XML_VALUE = this.CreateXmlTextValue(xmlDoc, strValue);
  2028.         XML_NODE.appendChild(XML_VALUE);
  2029.         return XML_NODE;
  2030.     },
  2031.  
  2032.     CreateXmlTextValue: function(xmlDoc, strValue) {
  2033.         var XML_VALUE = xmlDoc.createTextNode(strValue);
  2034.         return XML_VALUE;
  2035.     },
  2036.  
  2037.     GetXmlNodeValue: function(xmlNode, defaultValue) {
  2038.         if (typeof defaultValue == "undefined") defaultValue = "";
  2039.         var iTextNodeType = Components.interfaces.nsIDOMNode.TEXT_NODE;
  2040.         var iCDataNodeType = Components.interfaces.nsIDOMNode.CDATA_SECTION_NODE;
  2041.         if (xmlNode.childNodes.length == 1 &&
  2042.         (xmlNode.childNodes[0].nodeType == iTextNodeType
  2043.         || xmlNode.childNodes[0].nodeType == iCDataNodeType)) {
  2044.             return xmlNode.childNodes[0].nodeValue;
  2045.         }
  2046.         return defaultValue;
  2047.     },
  2048.  
  2049.     GetIntegerXmlNodeValue: function(xmlNode, iDefaultValue) {
  2050.         if (!iDefaultValue) iDefaultValue = 0;
  2051.  
  2052.         var strValue = this.GetXmlNodeValue(xmlNode);
  2053.         var iValue = parseInt(strValue);
  2054.         return (isNaN(iValue)) ? iDefaultValue : iValue;
  2055.     },
  2056.  
  2057.     GetBooleanXmlNodeValue: function(xmlNode, bDefaultValue) {
  2058.         var strValue = this.GetXmlNodeValue(xmlNode);
  2059.         if (!bDefaultValue) bDefaultValue = false;
  2060.         var bValue = bDefaultValue;
  2061.  
  2062.         if (strValue) {
  2063.             strValue = strValue.toLowerCase();
  2064.             if (strValue == "false")
  2065.                 bValue = false;
  2066.             else if (strValue == "true")
  2067.                 bValue = true;
  2068.         }
  2069.  
  2070.         return bValue;
  2071.     },
  2072.  
  2073.     SelectSingleNode: function(xmlDoc, strTagName) {
  2074.         try {
  2075.             var arrNodes = xmlDoc.getElementsByTagName(strTagName);
  2076.             if (arrNodes.length == 1)
  2077.                 return arrNodes.item(0);
  2078.             else if (arrNodes.length > 1) {
  2079.                 for (var i = 0; i < arrNodes.length; i++) {
  2080.                     if (arrNodes.item(i).parentNode.tagName == xmlDoc.tagName)
  2081.                         return arrNodes.item(i);
  2082.                 }
  2083.             }
  2084.             else
  2085.                 return null;
  2086.         }
  2087.         catch (ex) {
  2088.             Logging.LogToConsole(ex + "\n" + strTagName);
  2089.             return null;
  2090.         }
  2091.     },
  2092.  
  2093.     GetSingleNodeValue: function(xmlElement, strTagName, strDefaultValue) {
  2094.         var strValue = '';
  2095.         var xmlNode = this.SelectSingleNode(xmlElement, strTagName);
  2096.  
  2097.         if (xmlNode)
  2098.             strValue = this.GetXmlNodeValue(xmlNode);
  2099.  
  2100.         if (!strValue && typeof strDefaultValue != "undefined")
  2101.             strValue = strDefaultValue;
  2102.  
  2103.         return strValue;
  2104.     },
  2105.  
  2106.     GetSingleNodeValueAsBoolean: function(xmlElement, strTagName, bDefaultValue) {
  2107.         var strValue = '';
  2108.         var bValue = bDefaultValue;
  2109.         var xmlNode = this.SelectSingleNode(xmlElement, strTagName);
  2110.  
  2111.         if (xmlNode)
  2112.             strValue = this.GetXmlNodeValue(xmlNode);
  2113.  
  2114.         if (strValue) {
  2115.             strValue = strValue.toLowerCase();
  2116.             if (strValue == "false")
  2117.                 bValue = false;
  2118.             else if (strValue == "true")
  2119.                 bValue = true;
  2120.         }
  2121.  
  2122.         return bValue;
  2123.     },
  2124.  
  2125.     GetSingleNodeValueAsInteger: function(xmlElement, strTagName, defaultValue) {
  2126.         if (typeof (defaultValue) == "undefined") defaultValue = 0;
  2127.  
  2128.         var val = this.GetSingleNodeValue(xmlElement, strTagName);
  2129.         if (val != "" && val != null) return parseInt(val);
  2130.         else return defaultValue;
  2131.     },
  2132.  
  2133.     CreateXmlNodeString: function(strTagName, strValue) {
  2134.         return '<' + strTagName + '>' + strValue + '</' + strTagName + '>';
  2135.     },
  2136.  
  2137.     CreateXmlNodeStartString: function(strTagName) {
  2138.         return '<' + strTagName + '>';
  2139.     },
  2140.  
  2141.     CreateXmlNodeEndString: function(strTagName) {
  2142.         return '</' + strTagName + '>';
  2143.     }
  2144. };
  2145.  
  2146. var AlertXPCOM =
  2147. {
  2148.     manager: new FFAlert()
  2149. };
  2150. var ChatXPCOM =
  2151. {
  2152.     hashChatManagers: new HashArray(),
  2153.     room: ChatRoom, //reference to the object chat room
  2154.     
  2155.     getChatManager: function(strOriginalCTID) {
  2156.         var oChatManager = this.hashChatManagers.GetByID(strOriginalCTID);
  2157.         if (!oChatManager) {
  2158.             oChatManager = new ConduitChat();
  2159.             this.hashChatManagers.Add(strOriginalCTID, oChatManager);
  2160.         }
  2161.  
  2162.         return oChatManager;
  2163.     }
  2164. };
  2165. var CommonData =
  2166. {
  2167.     ConduitFolder: "conduit"
  2168. };
  2169.  
  2170. /*
  2171. var EmailNotifierXPCOM =
  2172. {
  2173.     hashManagers: new HashArray(),
  2174.  
  2175.     getManager: function(strOriginalCTID) {
  2176.         var oManager = this.hashManagers.GetByID(strOriginalCTID);
  2177.         if (!oManager) {
  2178.             oManager = new EmailNotifierManager();
  2179.             this.hashManagers.Add(strOriginalCTID, oManager);
  2180.         }
  2181.  
  2182.         return oManager;
  2183.     }
  2184. };*/
  2185. var TrusteXPCOM =
  2186. {
  2187.     trusteManager: new TrusteManager()
  2188. };
  2189. var AlertConsts =
  2190. {
  2191.     servicesBaseUrl: "http://alert.services.conduit.com",
  2192.     clientsBaseUrl : "http://alert.services.conduit.com",
  2193.     alertDBFilename: "alertDB.sqlite",
  2194.     
  2195.     //UI
  2196.     mainDialogPath: "chrome://iobitcom/content/alertMain.xul",
  2197.     settingsDialogPath: "chrome://iobitcom/content/alertSettings.xul",
  2198.     channelMessagesPreviewDialogPath: "chrome://iobitcom/content/alertPreview.xul",
  2199.     aboutDialogPath: "chrome://iobitcom/content/alertAbout.xul",
  2200.  
  2201.     firstMessageDelayMs: 1000,
  2202.     messageAfterFirstTimeAlert: 4000
  2203. };
  2204.  
  2205. if (AppInfo.isGecko19) AlertConsts.firstMessageDelayMs = 8000;
  2206. var AlertPrefConsts =
  2207. {
  2208.     prefix: "CommunityToolbar.alert",
  2209.     
  2210.     //login
  2211.     loginLastUpdateTime: "loginLastUpdateTime",
  2212.     loginIntervalMin: "loginIntervalMin",
  2213.     loginLastCheckTime: "loginLastCheckTime",
  2214.     userId: "userId",
  2215.     locale: "locale",
  2216.     alertEnabled: "alertEnabled",
  2217.     
  2218.     //login data
  2219.     userCloseIntervalMin: "userCloseIntervalMin",
  2220.     messageShowTimeSec: "messageShowTimeSec",
  2221.     showTrayIcon: "showTrayIcon",
  2222.     servicesServerUrl: "servicesServerUrl",
  2223.     clientsServerUrl: "clientsServerUrl",
  2224.     
  2225.     //alert info
  2226.     alertInfoLastCheckTime: "alertInfoLastCheckTime",
  2227.     alertInfoInterval: "alertInfoInterval",
  2228.     
  2229.     //feeds manager
  2230.     feedLCTPrefix: "feedLastCheckTime.",
  2231.     firstTimeAlertShown: "firstTimeAlertShown",
  2232.     
  2233.     //alert channel id for single toolbar (not mc or grouping)
  2234.     alertChannelId: "alertChannelId"
  2235. };
  2236. var AlertDBManager =
  2237. {
  2238.     dbFile: null,
  2239.  
  2240.     getDB: function() {
  2241.         var file = null;
  2242.         try {
  2243.             this.dbFile = Components.classes["@mozilla.org/file/directory_service;1"]
  2244.                      .getService(Components.interfaces.nsIProperties)
  2245.                      .get("ProfD", Components.interfaces.nsIFile);
  2246.  
  2247.             this.dbFile.append(CommonData.ConduitFolder);
  2248.             this.dbFile.append(AlertConsts.alertDBFilename);
  2249.  
  2250.             var bCreateDB = false;
  2251.             if (!this.dbFile.exists()) {
  2252.                 this._createDBFile();
  2253.                 bCreateDB = true;
  2254.             }
  2255.  
  2256.             var storageService = Components.classes["@mozilla.org/storage/service;1"]
  2257.                                 .getService(Components.interfaces.mozIStorageService);
  2258.             var dbConn = storageService.openDatabase(this.dbFile);
  2259.  
  2260.             if (bCreateDB)
  2261.                 this._createDB(dbConn);
  2262.  
  2263.             return dbConn;
  2264.         }
  2265.         catch (e) {
  2266.             Logging.LogToConsole(e);
  2267.             return null;
  2268.         }
  2269.     },
  2270.  
  2271.     deleteDB: function() {
  2272.         try {
  2273.             //delete DB file
  2274.             File.unlink(this.dbFile);
  2275.             //tell global cleanup manager to check if common folder should be deleted (if empty)
  2276.             CommonFolderManagment.cleanup();
  2277.         }
  2278.         catch (ex) {}
  2279.     },
  2280.  
  2281.     _createDBFile: function() {
  2282.         File.create(this.dbFile);
  2283.     },
  2284.  
  2285.     _createDB: function(dbConn) {
  2286.         try {
  2287.             dbConn.executeSimpleSQL('CREATE TABLE "Channel" ("ChannelId" INTEGER PRIMARY KEY  NOT NULL ,"LastUpdateTime" DATETIME DEFAULT CURRENT_TIMESTAMP , "IsEnabled" INTEGER DEFAULT 1)');
  2288.             dbConn.executeSimpleSQL('CREATE TABLE "Channel-Feed" ("ChannelId" INTEGER NOT NULL , "FeedId" INTEGER NOT NULL , PRIMARY KEY ("ChannelId", "FeedId"))');
  2289.             dbConn.executeSimpleSQL('CREATE TABLE "Channel-Source" ("SourceId" VARCHAR NOT NULL , "ChannelId" INTEGER NOT NULL , PRIMARY KEY ("SourceId", "ChannelId"))');
  2290.             dbConn.executeSimpleSQL('CREATE TABLE "Feed" ("FeedId" NUMERIC PRIMARY KEY  NOT NULL ,"Url" VARCHAR NOT NULL ,"Interval" INTEGER NOT NULL  DEFAULT 0 ,"LastCheckTime" DATETIME,"Title" Text,"ImageUrl" VARCHAR,"IsEnabled" INTEGER NOT NULL  DEFAULT 1 )');
  2291.             dbConn.executeSimpleSQL('CREATE TABLE "FeedItem" ("ItemGuid" VARCHAR PRIMARY KEY  NOT NULL ,"Title" VARCHAR,"PubDate" INTEGER,"IsHistory" INTEGER NOT NULL  DEFAULT 0 ,"FeedId" INTEGER NOT NULL  DEFAULT 0 , "Link" VARCHAR, "Description" TEXT)');
  2292.             dbConn.executeSimpleSQL('CREATE TABLE "Source" ("SourceId" VARCHAR PRIMARY KEY  NOT NULL )');
  2293.         }
  2294.         catch (ex) {
  2295.             Logging.DBLogToConsole("DB creation", dbConn.lastErrorString, ex, "")
  2296.         }
  2297.     }
  2298. }
  2299. var AlertFeedsDAL =
  2300. {
  2301.     dbConn: null,
  2302.     hashRegisteredSources: null,
  2303.  
  2304.     init: function() {
  2305.         try {
  2306.             this.dbConn = AlertDBManager.getDB();
  2307.  
  2308.             //store all registered sources in memory for faster access
  2309.             this.hashRegisteredSources = this.getRegisteredSources();
  2310.         } catch (e) { Logging.LogToConsole(e) }
  2311.     },
  2312.  
  2313.     unlink: function() {
  2314.         try {
  2315.             this.dbConn.close();
  2316.             AlertDBManager.deleteDB();
  2317.         }
  2318.         catch (ex) {
  2319.  
  2320.         }
  2321.     },
  2322.  
  2323.     refresh: function() {
  2324.         this.hashRegisteredSources = this.getRegisteredSources();
  2325.     },
  2326.  
  2327.     registerSource: function(strSource) {
  2328.         //source already registered, return
  2329.         if (this.hashRegisteredSources.Contains(strSource)) return;
  2330.  
  2331.         try {
  2332.             this.dbConn.executeSimpleSQL("INSERT INTO Source VALUES ('" + strSource + "')");
  2333.         }
  2334.         catch (ex) {
  2335.             Logging.DBLogToConsole("Source", this.dbConn.lastErrorString, ex);
  2336.         }
  2337.         //update in-memory sources hash
  2338.         this.hashRegisteredSources = this.getRegisteredSources();
  2339.     },
  2340.  
  2341.     unregisterSource: function(strSource) {
  2342.         //the source doesn't exists
  2343.         if (!this.hashRegisteredSources.Contains(strSource)) return;
  2344.  
  2345.         //delete from sources table
  2346.         this.dbConn.executeSimpleSQL("DELETE FROM Source WHERE SourceId='" + strSource + "'");
  2347.         //delete from Channel-Source relations
  2348.         this.dbConn.executeSimpleSQL("DELETE FROM [Channel-Source] WHERE SourceId='" + strSource + "'");
  2349.  
  2350.         this._syncChannels();
  2351.  
  2352.         //update in-memory sources hash
  2353.         this.hashRegisteredSources = this.getRegisteredSources();
  2354.     },
  2355.  
  2356.     getRegisteredSources: function() {
  2357.         var statement = null;
  2358.         var hashSources = new HashArray();
  2359.         try {
  2360.             statement = this.dbConn.createStatement("SELECT SourceId FROM Source");
  2361.             while (statement.executeStep())
  2362.                 hashSources.Add(statement.getUTF8String(0), true);
  2363.         }
  2364.         catch (ex) {
  2365.             Logging.DBLogToConsole("Source", this.dbConn.lastErrorString, ex);
  2366.         }
  2367.         finally {
  2368.             if (statement) this._finalizeStatement(statement);
  2369.         }
  2370.  
  2371.         return hashSources;
  2372.     },
  2373.  
  2374.     getRegisteredSourcesCount: function() {
  2375.         if (!this.hashRegisteredSources)
  2376.             return 0;
  2377.         else
  2378.             return this.hashRegisteredSources.Count();
  2379.     },
  2380.  
  2381.     addAlertChannels: function(strSource, arrNewChannels) {
  2382.         this._addNewChannels(strSource, arrNewChannels);
  2383.     },
  2384.  
  2385.     //returns true if there are new channels, false otherwise
  2386.     replaceAlertChannels: function(strSource, arrAlertChannels) {
  2387.         var hashChannelsIds = this._getChannelsIdsForSource(strSource);
  2388.         var arrNewChannels = new Array();
  2389.         var i;
  2390.  
  2391.         for (i = 0; i < arrAlertChannels.length; i++) {
  2392.             if (hashChannelsIds.Contains(arrAlertChannels[i]))
  2393.                 hashChannelsIds.GetByID(arrAlertChannels[i]).exists = true;
  2394.             else
  2395.                 arrNewChannels.push(arrAlertChannels[i]);
  2396.         }
  2397.  
  2398.         var arrChannelsToDelete = new Array();
  2399.         var o = null;
  2400.         for (i = 0; i < hashChannelsIds.Count(); i++) {
  2401.             o = hashChannelsIds.GetByIndex(i);
  2402.             if (!o.exists)
  2403.                 arrChannelsToDelete.push(o.key);
  2404.         }
  2405.  
  2406.         if (arrChannelsToDelete.length != 0)
  2407.             this._deleteChannelsFromChannelsSourceRelation(strSource, arrChannelsToDelete);
  2408.  
  2409.         if (arrNewChannels.length != 0) {
  2410.             this._addNewChannels(strSource, arrNewChannels);
  2411.             return true;
  2412.         }
  2413.         else
  2414.             return false;
  2415.     },
  2416.  
  2417.     //for login message
  2418.     getChannelsIdsArray: function() {
  2419.         var statement = this.dbConn.createStatement("SELECT ChannelId FROM Channel");
  2420.         var arrIds = new Array();
  2421.         try {
  2422.             while (statement.executeStep())
  2423.                 arrIds.push(statement.getInt32(0));
  2424.         }
  2425.         catch (ex) {
  2426.             Logging.DBLogToConsole("Channel", this.dbConn.lastErrorString, ex);
  2427.         }
  2428.         finally {
  2429.             if (statement) this._finalizeStatement(statement);
  2430.         }
  2431.  
  2432.         return arrIds;
  2433.     },
  2434.  
  2435.     //for alert info message
  2436.     getChannelsArray: function() {
  2437.         var arrChannels = new Array();
  2438.         try {
  2439.             var statement = this.dbConn.createStatement("SELECT ChannelId, LastUpdateTime, IsEnabled FROM Channel");
  2440.             var channel = null;
  2441.             while (statement.executeStep()) {
  2442.                 channel = new AlertChannel();
  2443.                 channel.init(statement.getInt32(0), statement.getString(1), statement.getInt32(2));
  2444.                 arrChannels.push(channel);
  2445.             }
  2446.         }
  2447.         catch (ex) {
  2448.             Logging.DBLogToConsole("Channel", this.dbConn.lastErrorString, ex);
  2449.         }
  2450.         finally {
  2451.             if (statement) this._finalizeStatement(statement);
  2452.         }
  2453.  
  2454.         return arrChannels;
  2455.     },
  2456.  
  2457.     //from login response
  2458.     updateChannelsAndFeeds: function(arrChannels) {
  2459.         if (!arrChannels || arrChannels.length == 0) return;
  2460.  
  2461.         var channel = null;
  2462.         var feed = null;
  2463.         var updatedFeedIdsArray = new Array();
  2464.  
  2465.         for (var i = 0; i < arrChannels.length; i++) {
  2466.             channel = arrChannels[i];
  2467.             this._updateChannel(channel);
  2468.             this._updateChannelFeedRelations(channel);
  2469.  
  2470.             if (channel.feeds) {
  2471.                 for (var j = 0; j < channel.feeds.length; j++) {
  2472.                     feed = channel.feeds[j];
  2473.                     updatedFeedIdsArray.push(feed.id);
  2474.                     this._updateFeed(feed);
  2475.                 }
  2476.             }
  2477.         }
  2478.  
  2479.         //set not changed feeds last check time to now, because there is no need to check them if the server returned "not modified"
  2480.         //on info response
  2481.         try {
  2482.             this.dbConn.executeSimpleSQL("UPDATE Feed SET LastCheckTime=DateTime('now') WHERE FeedId NOT IN (" + updatedFeedIdsArray.join(',') + ")");
  2483.         }
  2484.         catch (ex) {
  2485.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2486.         }
  2487.  
  2488.         this._syncFeeds();
  2489.     },
  2490.  
  2491.     //return feedItems + title and image from corresponding feed, for unshown items
  2492.     //to show items on startUp
  2493.     //returns an array of AlertFeedItem.
  2494.     getNewFeedItems: function() {
  2495.         var arrAlertFeedItems = new Array();
  2496.         var item = null;
  2497.         var strSql = "SELECT FeedItem.ItemGuid, FeedItem.Title, FeedItem.PubDate, FeedItem.Link, FeedItem.Description, ";
  2498.         strSql += "Feed.Title, Feed.ImageUrl, Feed.FeedId ";
  2499.         strSql += "FROM FeedItem, Feed ";
  2500.         strSql += "WHERE FeedItem.IsHistory = 0 AND FeedItem.FeedId = Feed.FeedId AND Feed.IsEnabled=1 AND (strftime('%s','now') - FeedItem.PubDate <= 86400000) ";
  2501.         strSql += "ORDER BY FeedItem.PubDate";
  2502.  
  2503.         try {
  2504.             var statement = this.dbConn.createStatement(strSql);
  2505.             while (statement.executeStep()) {
  2506.                 item = new AlertFeedItem();
  2507.                 item.init(statement.getUTF8String(1),       //title, 
  2508.                             statement.getUTF8String(3),     //link, 
  2509.                             statement.getUTF8String(4),     //description,
  2510.                             statement.getInt64(2),         //pubDate - int, 
  2511.                             statement.getInt32(0),          //guid, 
  2512.                             statement.getUTF8String(5),     //feedTitle,
  2513.                             statement.getUTF8String(6),     //feedImageUrl)
  2514.                             statement.getInt32(7))          //feedId)
  2515.  
  2516.                 arrAlertFeedItems.push(item);
  2517.             }
  2518.         }
  2519.         catch (ex) {
  2520.             Logging.DBLogToConsole("FeedItem, Feed", this.dbConn.lastErrorString, ex);
  2521.         }
  2522.         finally {
  2523.             if (statement) this._finalizeStatement(statement);
  2524.         }
  2525.  
  2526.         return arrAlertFeedItems;
  2527.     },
  2528.  
  2529.     //return an array of feeds to poll (time from last check is bigger then the interval
  2530.     getFeedsToPoll: function() {
  2531.         var strSql = "SELECT FeedId, Url FROM Feed WHERE (strftime('%M', 'now') - strftime('%M', LastCheckTime) > Interval OR LastCheckTime IS NULL)";
  2532.         var arrFeeds = new Array();
  2533.         var feed = null;
  2534.         try {
  2535.             var statement = this.dbConn.createStatement(strSql);
  2536.             while (statement.executeStep()) {
  2537.                 feed = new AlertFeed();
  2538.                 feed.init(statement.getInt32(0), statement.getUTF8String(1));
  2539.                 arrFeeds.push(feed);
  2540.             }
  2541.         }
  2542.         catch (ex) {
  2543.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2544.         }
  2545.         finally {
  2546.             if (statement) this._finalizeStatement(statement);
  2547.         }
  2548.  
  2549.         return arrFeeds;
  2550.     },
  2551.  
  2552.     //saves feed items and returns new (unshown) (Array of AlertFeedItems)
  2553.     saveFeedData: function(objFeedData, feedId) {
  2554.         this._updateFeedDataFromPoll(objFeedData.feedData, feedId);
  2555.         return this._saveFeedItems(objFeedData, feedId);
  2556.     },
  2557.  
  2558.     //update lastCheckTime to now on feed poll.
  2559.     updateFeedLastCheckTime: function(feedId) {
  2560.         try {
  2561.             this.dbConn.executeSimpleSQL("UPDATE Feed SET LastCheckTime=datetime('now') WHERE FeedId=" + feedId);
  2562.         }
  2563.         catch (ex) {
  2564.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2565.         }
  2566.     },
  2567.  
  2568.     getFeedsSortedHashArray: function() {
  2569.         var hashFeeds = new HashArray();
  2570.         var feed = null;
  2571.         try {
  2572.             var statement = this.dbConn.createStatement("SELECT FeedId, Title, IsEnabled FROM Feed ORDER BY Title");
  2573.             while (statement.executeStep()) {
  2574.                 feed = new AlertFeed();
  2575.                 feed.init(statement.getInt32(0), "", 0, statement.getUTF8String(1), "", "", statement.getInt32(2));
  2576.                 hashFeeds.Add(feed.id, feed);
  2577.             }
  2578.         }
  2579.         catch (ex) {
  2580.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2581.         }
  2582.         finally {
  2583.             if (statement) this._finalizeStatement(statement);
  2584.         }
  2585.  
  2586.         return hashFeeds;
  2587.     },
  2588.  
  2589.     reverseFeedsEnableState: function(arrFeedsIds) {
  2590.         try {
  2591.             this.dbConn.executeSimpleSQL("UPDATE Feed SET IsEnabled = NOT IsEnabled WHERE FeedId IN (" + arrFeedsIds.join(',') + ")");
  2592.         }
  2593.         catch (ex) {
  2594.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2595.         }
  2596.     },
  2597.  
  2598.     //returns a hashArray {key: FeedId, value: Array of AlertFeedItem)
  2599.     getFeedItemsHash: function() {
  2600.         var hashFeedItems = new HashArray();
  2601.         var item = null;
  2602.         var arrItems = null;
  2603.         var strSql = "SELECT FeedItem.ItemGuid, FeedItem.Title, FeedItem.PubDate, FeedItem.Link, FeedItem.Description, ";
  2604.         strSql += "Feed.Title, Feed.ImageUrl, Feed.FeedId ";
  2605.         strSql += "FROM FeedItem, Feed ";
  2606.         strSql += "WHERE FeedItem.FeedId = Feed.FeedId AND Feed.IsEnabled=1";
  2607.         try {
  2608.             var statement = this.dbConn.createStatement(strSql);
  2609.             while (statement.executeStep()) {
  2610.                 item = new AlertFeedItem();
  2611.                 item.init(statement.getUTF8String(1),       //title, 
  2612.                             statement.getUTF8String(3),     //link, 
  2613.                             statement.getUTF8String(4),     //description,
  2614.                             statement.getInt64(2),          //pubDate - int, 
  2615.                             statement.getInt32(0),          //guid, 
  2616.                             statement.getUTF8String(5),     //feedTitle,
  2617.                             statement.getUTF8String(6),     //feedImageUrl
  2618.                             statement.getInt32(7))          //feedId )
  2619.  
  2620.                 if (hashFeedItems.Contains(item.feedId)) {
  2621.                     arrItems = hashFeedItems.GetByID(item.feedId);
  2622.                     arrItems.push(item);
  2623.                 }
  2624.                 else {
  2625.                     arrItems = new Array();
  2626.                     arrItems.push(item);
  2627.                     hashFeedItems.Add(item.feedId, arrItems);
  2628.                 }
  2629.             }
  2630.         }
  2631.         catch (ex) {
  2632.             Logging.DBLogToConsole("FeedItem, Feed", this.dbConn.lastErrorString, ex);
  2633.         }
  2634.         finally {
  2635.             if (statement) this._finalizeStatement(statement);
  2636.         }
  2637.  
  2638.         return hashFeedItems;
  2639.     },
  2640.  
  2641.     //update shown feed items
  2642.     updateShownFeedItems: function(arrFeedItemsGuids) {
  2643.         try {
  2644.             this.dbConn.executeSimpleSQL("UPDATE FeedItem SET IsHistory=1 WHERE ItemGuid IN (" + arrFeedItemsGuids.join(',') + ")");
  2645.         }
  2646.         catch (ex) {
  2647.             Logging.DBLogToConsole("FeedItem", this.dbConn.lastErrorString, ex);
  2648.         }
  2649.     },
  2650.  
  2651.     getFirstChannelByFeedId: function(feedId) {
  2652.         var channelId;
  2653.         try {
  2654.             var statement = this.dbConn.createStatement("SELECT ChannelId FROM [Channel-Feed] WHERE FeedId=" + feedId + " LIMIT 1");
  2655.             while (statement.executeStep()) {
  2656.                 channelId = statement.getInt32(0);
  2657.             }
  2658.         }
  2659.         catch (ex) {
  2660.             Logging.DBLogToConsole("[Channel-Feed]", this.dbConn.lastErrorString, ex);
  2661.         }
  2662.         finally {
  2663.             if (statement) this._finalizeStatement(statement);
  2664.         }
  2665.  
  2666.         return channelId;
  2667.     },
  2668.  
  2669.     getFirstChannel: function() {
  2670.         var channelId;
  2671.         try {
  2672.             var statement = this.dbConn.createStatement("SELECT ChannelId FROM [Channel-Feed] LIMIT 1");
  2673.             while (statement.executeStep()) {
  2674.                 channelId = statement.getInt32(0);
  2675.             }
  2676.         }
  2677.         catch (ex) {
  2678.             Logging.DBLogToConsole("[Channel-Feed]", this.dbConn.lastErrorString, ex);
  2679.         }
  2680.         finally {
  2681.             if (statement) this._finalizeStatement(statement);
  2682.         }
  2683.  
  2684.         return channelId;
  2685.     },
  2686.  
  2687.     isFeedsExists: function() {
  2688.         var feedId = null;
  2689.         try {
  2690.             var statement = this.dbConn.createStatement("SELECT FeedId FROM Feed LIMIT 1");
  2691.             while (statement.executeStep()) {
  2692.                 feedId = statement.getInt32(0);
  2693.             }
  2694.         }
  2695.         catch (ex) {
  2696.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2697.         }
  2698.         finally {
  2699.             if (statement) this._finalizeStatement(statement);
  2700.         }
  2701.  
  2702.         return feedId;
  2703.     },
  2704.  
  2705.     isFeedEnabled: function(feedId) {
  2706.         var bIsEnabled = false;
  2707.         try {
  2708.             var statement = this.dbConn.createStatement("SELECT IsEnabled FROM Feed WHERE FeedId=" + feedId + " LIMIT 1");
  2709.             while (statement.executeStep()) {
  2710.                 bIsEnabled = statement.getInt32(0);
  2711.             }
  2712.         }
  2713.         catch (ex) {
  2714.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2715.         }
  2716.         finally {
  2717.             if (statement) this._finalizeStatement(statement);
  2718.         }
  2719.  
  2720.         return bIsEnabled;
  2721.     },
  2722.  
  2723.     //get feed for welcome alert after adding alert via API.
  2724.     getFeedItem: function(feedId) {
  2725.         var oFeedItem = null;
  2726.         try {
  2727.             oFeedItem = new AlertFeedItem();
  2728.             var statement = this.dbConn.createStatement("SELECT FeedId, Title, ImageUrl FROM Feed WHERE FeedId=" + feedId + " LIMIT 1");
  2729.             while (statement.executeStep()) {
  2730.                 oFeedItem.feedId = statement.getInt32(0);
  2731.                 oFeedItem.feedTitle = statement.getUTF8String(1);
  2732.                 oFeedItem.headerImage = statement.getUTF8String(2);
  2733.                 oFeedItem.sendUsage = false;
  2734.             }
  2735.         }
  2736.         catch (ex) {
  2737.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2738.         }
  2739.         finally {
  2740.             if (statement) this._finalizeStatement(statement);
  2741.         }
  2742.  
  2743.         return oFeedItem;
  2744.     },
  2745.  
  2746.     //update feed data polled from feed url
  2747.     _updateFeedDataFromPoll: function(feedCustomData, feedId) {
  2748.         try {
  2749.             var statement = this.dbConn.createStatement("UPDATE Feed SET LastCheckTime=datetime('now'), Title=?1, ImageUrl=?2 WHERE FeedId=?3");
  2750.             statement.bindUTF8StringParameter(0, feedCustomData.title);
  2751.             statement.bindUTF8StringParameter(1, feedCustomData.imageUrl);
  2752.             statement.bindInt32Parameter(2, feedId);
  2753.             statement.execute();
  2754.         }
  2755.         catch (ex) {
  2756.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2757.         }
  2758.         finally {
  2759.             if (statement) this._finalizeStatement(statement);
  2760.         }
  2761.     },
  2762.  
  2763.     //from polled feed
  2764.     _saveFeedItems: function(objFeedDataArray, feedId) {
  2765.         //load current items into hash
  2766.         var hashCurrentFeedItems = this._getFeedItemsByFeedId(feedId);
  2767.         var newFeedItem = null;
  2768.         var arrNewItems = new Array();
  2769.         var alertItem = null;
  2770.  
  2771.         for (var i = 0; i < objFeedDataArray.length; i++) {
  2772.             newFeedItem = objFeedDataArray[i];
  2773.             if (hashCurrentFeedItems.Contains(newFeedItem.guid))
  2774.             //update is histroy from DB, in order to save the current state of an existing item
  2775.             {
  2776.                 newFeedItem.isHistory = hashCurrentFeedItems.GetByID(newFeedItem.guid).isHistory;
  2777.             }
  2778.             else {
  2779.                 alertItem = new AlertFeedItem();
  2780.                 alertItem.initFromFeedItem(newFeedItem, objFeedDataArray.feedData.title, objFeedDataArray.feedData.imageUrl, feedId);
  2781.                 arrNewItems.push(alertItem);
  2782.             }
  2783.         }
  2784.  
  2785.         //delete the old data
  2786.         this._deleteFeedItems(feedId);
  2787.         //add the current (received from feed poll)
  2788.         this._addFeedItems(objFeedDataArray, feedId);
  2789.  
  2790.         //return the unshown items (Array of AlertFeedItems)
  2791.         return arrNewItems;
  2792.     },
  2793.  
  2794.     _getFeedItemsByFeedId: function(feedId) {
  2795.         var statement = this.dbConn.createStatement("SELECT ItemGuid, IsHistory FROM FeedItem WHERE FeedId=" + feedId);
  2796.         var hashFeeds = new HashArray();
  2797.         var feedItem = null;
  2798.         try {
  2799.             while (statement.executeStep()) {
  2800.                 feedItem = new FeedCustomItem();
  2801.                 feedItem.guid = statement.getInt32(0);
  2802.                 feedItem.isHistory = statement.getInt32(1);
  2803.                 hashFeeds.Add(feedItem.guid, feedItem);
  2804.             }
  2805.         }
  2806.         catch (ex) {
  2807.             Logging.DBLogToConsole("FeedItem", this.dbConn.lastErrorString, ex);
  2808.         }
  2809.         finally {
  2810.             if (statement) this._finalizeStatement(statement);
  2811.         }
  2812.  
  2813.         return hashFeeds;
  2814.     },
  2815.  
  2816.     _deleteFeedItems: function(feedId) {
  2817.         try {
  2818.             this.dbConn.executeSimpleSQL("DELETE FROM FeedItem WHERE FeedId=" + feedId);
  2819.         }
  2820.         catch (ex) {
  2821.             Logging.DBLogToConsole("FeedItem", this.dbConn.lastErrorString, ex);
  2822.         }
  2823.     },
  2824.  
  2825.     _addFeedItems: function(objFeedItemsArray, feedId) {
  2826.         var feedItem = null;
  2827.         var statement;
  2828.         for (var i = 0; i < objFeedItemsArray.length; i++) {
  2829.             feedItem = objFeedItemsArray[i];
  2830.             statement = this.dbConn.createStatement("INSERT INTO FeedItem VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)");
  2831.             statement.bindInt32Parameter(0, feedItem.guid);
  2832.             statement.bindUTF8StringParameter(1, feedItem.title);
  2833.             statement.bindInt64Parameter(2, Date.parse(feedItem.pubDate));
  2834.             statement.bindInt32Parameter(3, feedItem.isHistory);
  2835.             statement.bindInt32Parameter(4, feedId);
  2836.             statement.bindUTF8StringParameter(5, feedItem.link);
  2837.             statement.bindUTF8StringParameter(6, feedItem.description);
  2838.             try {
  2839.                 statement.execute();
  2840.             }
  2841.             catch (ex) {
  2842.                 Logging.DBLogToConsole("FeedItem", this.dbConn.lastErrorString, ex);
  2843.             }
  2844.             finally {
  2845.                 if (statement) this._finalizeStatement(statement);
  2846.             }
  2847.         }
  2848.     },
  2849.  
  2850.     _getChannelsIdsForSource: function(strSource) {
  2851.         var statement = null;
  2852.         var hashChannels = new HashArray();
  2853.         var o = null;
  2854.         var channelId;
  2855.         try {
  2856.             statement = this.dbConn.createStatement("SELECT ChannelId FROM [Channel-Source] WHERE SourceId='" + strSource + "'");
  2857.             while (statement.executeStep()) {
  2858.                 channelId = statement.getInt32(0);
  2859.                 o = new Object();
  2860.                 o.exists = false;
  2861.                 o.key = channelId;
  2862.                 hashChannels.Add(channelId, o);
  2863.             }
  2864.         }
  2865.         catch (ex) {
  2866.             Logging.DBLogToConsole("Channel-Source", this.dbConn.lastErrorString, ex);
  2867.         }
  2868.         finally {
  2869.             if (statement) this._finalizeStatement(statement);
  2870.         }
  2871.  
  2872.         return hashChannels;
  2873.     },
  2874.  
  2875.     //private, used in updateChannelsAndFeeds
  2876.     _updateChannel: function(channel) {
  2877.         //new channels are added from toolbar, so there is no need to check if channel exists here
  2878.         try {
  2879.             this.dbConn.executeSimpleSQL("UPDATE Channel SET LastUpdateTime='" + channel.lastUpdateTime + "' WHERE ChannelId=" + channel.id);
  2880.         }
  2881.         catch (ex) {
  2882.             Logging.DBLogToConsole("Channel", this.dbConn.lastErrorString, ex);
  2883.         }
  2884.     },
  2885.  
  2886.     //private, used in updateChannelsAndFeeds
  2887.     _updateChannelFeedRelations: function(channel) {
  2888.         //delete old relations for this channel
  2889.         try {
  2890.             this.dbConn.executeSimpleSQL("DELETE FROM [Channel-Feed] WHERE ChannelId = " + channel.id);
  2891.         }
  2892.         catch (ex) {
  2893.             Logging.DBLogToConsole("Channel-Feed", this.dbConn.lastErrorString, ex);
  2894.         }
  2895.  
  2896.         //no new ones to add, exit
  2897.         if (channel.feeds.length == 0) return;
  2898.  
  2899.         //add the new ones
  2900.         var feed = null;
  2901.         for (var i = 0; i < channel.feeds.length; i++) {
  2902.             feed = channel.feeds[i];
  2903.             try {
  2904.                 this.dbConn.executeSimpleSQL("INSERT INTO [Channel-Feed] VALUES(" + channel.id + "," + feed.id + ")");
  2905.             }
  2906.             catch (ex) {
  2907.                 Logging.DBLogToConsole("Channel-Feed", this.dbConn.lastErrorString, ex);
  2908.             }
  2909.         }
  2910.     },
  2911.  
  2912.     //private, used in updateChannelsAndFeeds
  2913.     _updateFeed: function(feed) {
  2914.         var statement;
  2915.         //update
  2916.         if (this._isFeedExist(feed.id)) {
  2917.             statement = this.dbConn.createStatement("UPDATE Feed SET Url=?1, Interval=?2, LastCheckTime=null, Title=?3 WHERE FeedId=?4");
  2918.             statement.bindUTF8StringParameter(0, feed.url);
  2919.             statement.bindInt32Parameter(1, feed.interval);
  2920.             statement.bindUTF8StringParameter(2, feed.title);
  2921.             statement.bindInt32Parameter(3, feed.id);
  2922.         }
  2923.         //add
  2924.         else {
  2925.             statement = this.dbConn.createStatement("INSERT INTO Feed VALUES (?1, ?2, ?3, null, ?4, '', 1)");
  2926.             statement.bindInt32Parameter(0, feed.id);
  2927.             statement.bindUTF8StringParameter(1, feed.url);
  2928.             statement.bindInt32Parameter(2, feed.interval);
  2929.             statement.bindUTF8StringParameter(3, feed.title);
  2930.         }
  2931.  
  2932.         try {
  2933.             statement.execute();
  2934.         }
  2935.         catch (ex) {
  2936.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2937.         }
  2938.         finally {
  2939.             if (statement) this._finalizeStatement(statement);
  2940.         }
  2941.     },
  2942.  
  2943.     _isFeedExist: function(feedId) {
  2944.         var statement = this.dbConn.createStatement("SELECT FeedId FROM Feed WHERE FeedId=" + feedId);
  2945.         var bExists;
  2946.         try {
  2947.             if (statement.executeStep() && statement.getInt32(0))
  2948.                 bExists = true;
  2949.             else
  2950.                 bExists = false;
  2951.         }
  2952.         catch (ex) {
  2953.             bExists = false;
  2954.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  2955.         }
  2956.  
  2957.         finally {
  2958.             if (statement) this._finalizeStatement(statement);
  2959.         }
  2960.  
  2961.         return bExists;
  2962.     },
  2963.  
  2964.     _isChannelExists: function(channelId) {
  2965.         var chId = null;
  2966.         try {
  2967.             var statement = this.dbConn.createStatement("SELECT ChannelId FROM Channel WHERE ChannelId=" + channelId + " LIMIT 1");
  2968.             while (statement.executeStep())
  2969.                 chId = statement.getInt32(0);
  2970.         }
  2971.         catch (ex) {
  2972.             Logging.DBLogToConsole("Channel", this.dbConn.lastErrorString, ex);
  2973.         }
  2974.  
  2975.         finally {
  2976.             if (statement) this._finalizeStatement(statement);
  2977.         }
  2978.  
  2979.         return chId != null;
  2980.     },
  2981.  
  2982.     _isChannelSourceExists: function(channelId, sourceId) {
  2983.         var chId = null;
  2984.         try {
  2985.             var statement = this.dbConn.createStatement("SELECT ChannelId FROM [Channel-Source] WHERE ChannelId=" + channelId + " AND SourceId='" + sourceId + "' LIMIT 1");
  2986.             while (statement.executeStep())
  2987.                 chId = statement.getInt32(0);
  2988.         }
  2989.         catch (ex) {
  2990.             Logging.DBLogToConsole("Channel-Source", this.dbConn.lastErrorString, ex);
  2991.         }
  2992.  
  2993.         finally {
  2994.             if (statement) this._finalizeStatement(statement);
  2995.         }
  2996.  
  2997.         return chId != null;
  2998.     },
  2999.  
  3000.     _deleteChannelsFromChannelsSourceRelation: function(sourceId, arrChannelsIds) {
  3001.         try {
  3002.             this.dbConn.executeSimpleSQL("DELETE FROM [Channel-Source] WHERE SourceId='" + sourceId + "' AND ChannelId IN (" + arrChannelsIds.join(',') + ")");
  3003.         }
  3004.         catch (ex) {
  3005.             Logging.DBLogToConsole("Channel-Source", this.dbConn.lastErrorString, ex);
  3006.         }
  3007.  
  3008.         this._syncChannels();
  3009.     },
  3010.  
  3011.     _addNewChannels: function(sourceId, arrChannelsIds) {
  3012.         var channelId;
  3013.         for (var i = 0; i < arrChannelsIds.length; i++) {
  3014.             channelId = arrChannelsIds[i];
  3015.             //insert into channel-source table
  3016.             if (!this._isChannelSourceExists(channelId, sourceId)) {
  3017.                 try {
  3018.                     this.dbConn.executeSimpleSQL("INSERT INTO [Channel-Source] VALUES('" + sourceId + "'," + channelId + ")");
  3019.                 }
  3020.                 catch (ex) {
  3021.                     Logging.DBLogToConsole("Channel-Source", this.dbConn.lastErrorString, ex);
  3022.                 }
  3023.             }
  3024.  
  3025.             //if the channel is not exists, add it to channels DB with lastCheckTime = null
  3026.             if (!this._isChannelExists(channelId)) {
  3027.                 try {
  3028.                     this.dbConn.executeSimpleSQL("INSERT INTO Channel VALUES('" + channelId + "','',1)");
  3029.                 }
  3030.                 catch (ex) {
  3031.                     Logging.DBLogToConsole("Channel", this.dbConn.lastErrorString, ex);
  3032.                 }
  3033.             }
  3034.         }
  3035.     },
  3036.  
  3037.     //remove unused channels according to Channel-Source table
  3038.     _syncChannels: function() {
  3039.         try {
  3040.             this.dbConn.executeSimpleSQL("DELETE FROM Channel WHERE ChannelId NOT IN (SELECT ChannelId FROM [Channel-Source])");
  3041.             this.dbConn.executeSimpleSQL("DELETE FROM [Channel-Feed] WHERE ChannelId NOT IN (SELECT ChannelId FROM Channel)");
  3042.         }
  3043.         catch (ex) {
  3044.             Logging.DBLogToConsole("Channel", this.dbConn.lastErrorString, ex);
  3045.         }
  3046.  
  3047.         this._syncFeeds();
  3048.     },
  3049.  
  3050.     //remove unused feeds according to Channel-Feed table
  3051.     _syncFeeds: function() {
  3052.         try {
  3053.             this.dbConn.executeSimpleSQL("DELETE FROM Feed WHERE FeedId NOT IN (SELECT FeedId FROM [Channel-Feed])");
  3054.         }
  3055.         catch (ex) {
  3056.             Logging.DBLogToConsole("Feed", this.dbConn.lastErrorString, ex);
  3057.         }
  3058.  
  3059.         this._syncFeedItems();
  3060.     },
  3061.  
  3062.     //remove unused feedItems according to Feeds table
  3063.     _syncFeedItems: function() {
  3064.         try {
  3065.             this.dbConn.executeSimpleSQL("DELETE FROM FeedItem WHERE FeedId NOT IN (SELECT FeedId FROM Feed)");
  3066.         }
  3067.         catch (ex) {
  3068.             Logging.DBLogToConsole("FeedItem", this.dbConn.lastErrorString, ex);
  3069.         }
  3070.     },
  3071.  
  3072.     _finalizeStatement: function(statement) {
  3073.         if (statement.finalize)
  3074.             statement.finalize();
  3075.         else
  3076.             statement.reset();
  3077.     }
  3078. };
  3079. function AlertFeedItem() {
  3080.     this.feedTitle = "";
  3081.     this.headerImage = "";
  3082.     this.feedId = 0;
  3083.     this.headerText = "";
  3084.     this.sendUsage = true;
  3085.     this.isInternal = false;
  3086.  
  3087.     this.init = function(title, link, description, pubDate, guid, feedTitle, feedImageUrl, feedId) {
  3088.         this.link = link;
  3089.         this.title = title;
  3090.         this.description = description;
  3091.         this.pubDate = pubDate;
  3092.         this.guid = guid;
  3093.         this.feedTitle = feedTitle;
  3094.         this.headerImage = feedImageUrl;
  3095.         this.feedId = feedId;
  3096.     };
  3097.  
  3098.     this.initFromFeedItem = function(feedItem, feedTitle, feedImageUrl, feedId) {
  3099.         this.link = feedItem.link;
  3100.         this.title = feedItem.title;
  3101.         this.description = feedItem.description;
  3102.         this.pubDate = feedItem.pubDate;
  3103.         this.guid = feedItem.guid;
  3104.         this.feedTitle = feedTitle;
  3105.         this.headerImage = feedImageUrl;
  3106.         this.feedId = feedId;
  3107.     };
  3108. };
  3109.  
  3110. AlertFeedItem.prototype = new FeedCustomItem();
  3111. function AlertItem(headerText, headerCssStyle, headerImg, msgHtml, sendUsage, guid, isInternal, feedId, idExpirationSec) {
  3112.     this.__defineGetter__("headerText", function() { return headerText; });
  3113.     this.__defineGetter__("headerCssStyle", function() { return headerCssStyle; });
  3114.     this.__defineGetter__("headerImage", function() { return headerImg; });
  3115.     this.__defineGetter__("msgHtml", function() { return msgHtml; });
  3116.     this.__defineGetter__("sendUsage", function() { return sendUsage; });
  3117.     this.__defineGetter__("isInternal", function() { return isInternal; });
  3118.     this.__defineGetter__("guid", function() { return guid; });
  3119.     this.__defineGetter__("feedId", function() { return feedId; });
  3120.  
  3121.     this.toXMLString = function() {
  3122.         if (typeof idExpirationSec == "undefined") idExpirationSec = 60 * 4;
  3123.         var xml = '<instant_alerts_channel><author>TOOLBAR_NAME</author><id>FB_ALERT</id><feed><title></title><id></id><alert_item><guid>' + guid +
  3124.                 '</guid><timeout_sec>10</timeout_sec><id_expiration_timeout_sec>' + idExpirationSec + '</id_expiration_timeout_sec>' +
  3125.                 '<content><html><width>300' +
  3126.                 '</width><height>80' +
  3127.                 '</height><code><raw><![CDATA[' + '<html xmlns="http://www.w3.org/1999/xhtml"><head><style type="text/css">body{margin:2px;} .ebLink{color: #004498;} .ebLink:hover{text-decoration: underline;} .msgText{font-family:Arial; font-size: 11px;}</style><title>Untitled Page</title></head><body>'
  3128.                 + msgHtml + '</body></html>' +
  3129.                 ']]></raw></code></html></content><gui><height>140' +
  3130.                 '</height><width>310' +
  3131.                 '</width><window_title><image><url>' + headerImg + '</url></image><text>' + headerText + '</text></window_title></gui></alert_item></feed></instant_alerts_channel>';
  3132.  
  3133.         return xml;
  3134.     };
  3135. };
  3136.  
  3137.  
  3138. function AlertChannel() {
  3139.     var NOT_MODIFIED = "NOT_MODIFIED";
  3140.     
  3141.     this.id = "";
  3142.     this.lastUpdateTime = "";
  3143.     this.isModified = true;
  3144.     this.feeds = null;
  3145.     this.isEnabled = true;
  3146.  
  3147.     this.init = function(id, lastUpdateTime) {
  3148.         this.id = id;
  3149.         if (!lastUpdateTime) lastUpdateTime = 0;
  3150.         this.lastUpdateTime = lastUpdateTime;
  3151.     };
  3152.  
  3153.     this.initFromXml = function(xmlChannel) {
  3154.         if (!xmlChannel || xmlChannel.tagName != "CHANNEL") return;
  3155.  
  3156.         this.id = XML.GetSingleNodeValue(xmlChannel, "ID");
  3157.         //lastUpdateTime can be "NOT_MODIFIED", then there is not reason to check the feeds on this channel,
  3158.         //the feeds of this channel can be set to last check time = now.
  3159.         //if modified, then update last check time of all feeds to "0", in order to get now, and check feeds now.
  3160.         this.lastUpdateTime = XML.GetSingleNodeValue(xmlChannel, "LAST_UPDATE_TIME");
  3161.         if (this.lastUpdateTime == NOT_MODIFIED)
  3162.             this.isModified = false;
  3163.     };
  3164. };
  3165. function AlertFeed() {
  3166.     this.id = "";
  3167.     this.url = "";
  3168.     this.interval = 0; //minutes
  3169.     this.title = "";
  3170.     this.channelId = "";
  3171.     this.lastCheckTime = "";
  3172.     this.isEnabled = true;
  3173.     this.feedItems; //feed items array
  3174.  
  3175.     this.init = function(id, url, interval, title, channelId, lastCheckTime, isEnabled) {
  3176.         this.id = id;
  3177.         this.url = url;
  3178.         this.interval = interval;
  3179.         this.title = title;
  3180.         this.channelId = channelId;
  3181.         this.lastCheckTime = lastCheckTime;
  3182.         this.isEnabled = isEnabled;
  3183.     };
  3184.     
  3185.     this.initFromXml = function(xmlFeed, channelId) {
  3186.         if (!xmlFeed || xmlFeed.tagName != "FEED") return;
  3187.  
  3188.         this.id = XML.GetSingleNodeValue(xmlFeed, "ID");
  3189.         this.url = XML.GetSingleNodeValue(xmlFeed, "URL");
  3190.         this.interval = XML.GetSingleNodeValue(xmlFeed, "INTERVAL");
  3191.         this.title = XML.GetSingleNodeValue(xmlFeed, "TITLE");
  3192.         this.channelId = channelId;
  3193.     };
  3194. };
  3195. function FFAlert() {
  3196.     var FF_EXTERNAL_TOOLBAR_ID = "FF_TB_EXT";
  3197.     var _alertManager = null;
  3198.     var _init = false;
  3199.     this.isInit = false;
  3200.  
  3201.     this.register = function(strOriginalCTID) {
  3202.         var bSuccess = false;
  3203.         if (!_init) {
  3204.             if (AppInfo.OS == AppInfo.WIN && !PrefService.GetPref("conduit.alertForceInternal")) {
  3205.                 //try to init external alert
  3206.                 _alertManager = new ExternalAlertManager();
  3207.                 bSuccess = _alertManager.isInit();
  3208.             }
  3209.  
  3210.             if (!bSuccess && AppInfo.isGecko18) {
  3211.                 _alertManager = new InternalAlertManager();
  3212.                 _alertManager.init();
  3213.                 bSuccess = true;
  3214.             }
  3215.  
  3216.             _init = true;
  3217.             if (bSuccess) this.isInit = true;
  3218.         }
  3219.  
  3220.         if (bSuccess)
  3221.             _alertManager.register(strOriginalCTID);
  3222.     };
  3223.  
  3224.     this.unregister = function(strOriginalCTID) {
  3225.         _alertManager.unregister(strOriginalCTID);
  3226.     };
  3227.  
  3228.     this.addExternalAlertChannel = function(iAlertChannelId) {
  3229.         var arr = new Array();
  3230.         arr.push(iAlertChannelId);
  3231.         _alertManager.addAlertChannels(FF_EXTERNAL_TOOLBAR_ID, arr);
  3232.     };
  3233.  
  3234.     this.addMyStuffAlertChannel = function(iAlertChannelId, providerName) {
  3235.         var arr = new Array();
  3236.         arr.push(iAlertChannelId);
  3237.         _alertManager.addMyStuffAlertChannels(FF_EXTERNAL_TOOLBAR_ID, arr, providerName);
  3238.     };
  3239.  
  3240.     this.replaceChannelIds = function(strOriginalCTID, arrChannelIds) {
  3241.         _alertManager.replaceAlertChannels(strOriginalCTID, arrChannelIds);
  3242.     };
  3243.  
  3244.     this.openSettingsDialog = function(strOriginalCTID, win) {
  3245.         _alertManager.openSettingsDialog(strOriginalCTID, win);
  3246.     };
  3247.  
  3248.     this.refresh = function(isForceRefresh) {
  3249.         //isForceRefresh - for future use
  3250.         _alertManager.refresh();
  3251.     };
  3252.  
  3253.     this.alertEnabled = function(value) {
  3254.         return _alertManager.alertEnabled(value);
  3255.     };
  3256.  
  3257.     this.getInternalAlert = function() {   
  3258.         if (_alertManager instanceof InternalAlertManager)
  3259.             return _alertManager;
  3260.         else
  3261.             return null;
  3262.     };
  3263.  
  3264.     this.sendInternalAlert = function(alertItem) {
  3265.         _alertManager.sendInternalAlert(alertItem);
  3266.     };
  3267. };
  3268. function AlertFeedsManager(onNewItemCallback, onNewItemCallbackThis) {
  3269.     //TODO: set timer to check the feeds, think where this time should be, in order not to get same feed twice, 
  3270.     //at the time that first request didn't return yet.
  3271.     //var URL_POSTFIX = "Alerts/AlertServices.asmx/GetHostedFeedRss?alertId={0}&alertFeedId={1}";
  3272.     var oTimer = null;
  3273.     var oTimer_IntervalSec = 30; //sec
  3274.     var sendFeedsInterval=  5* 60 * 1000;
  3275.     var sendFeedsIntervalMethod =null;
  3276.     var that = this;
  3277.  
  3278.     this.init = function() {
  3279.         this.initFeedsToShow();
  3280.         this._initFeedsToPoll();
  3281.         this.startIntervalForFeeds();
  3282.     };
  3283.  
  3284.     this.startIntervalForFeeds = function() {
  3285.         this.stopIntervalForFeeds();
  3286.  
  3287.         sendFeedsIntervalMethod = setInterval(function() { that.initFeedsToShow(); }, sendFeedsInterval);
  3288.     };
  3289.  
  3290.     this.stopIntervalForFeeds = function() {
  3291.         if (sendFeedsIntervalMethod)
  3292.             clearInterval(sendFeedsIntervalMethod);
  3293.         
  3294.         sendFeedsIntervalMethod = null;
  3295.     };
  3296.  
  3297.     this.reInit = function() {
  3298.         this.shutdown();
  3299.         this._initFeedsToPoll();
  3300.     };
  3301.  
  3302.     this.shutdown = function() {
  3303.         clearTimeout(oTimer);
  3304.     };
  3305.  
  3306.     this.initFeedsToShow = function() {
  3307.     var arrAlertFeedItems = AlertFeedsDAL.getNewFeedItems();
  3308.         if (!arrAlertFeedItems || arrAlertFeedItems.length == 0) {
  3309.             return;
  3310.         }
  3311.         this._pushNewItems(arrAlertFeedItems);
  3312.     };
  3313.  
  3314.     this._pushNewItems = function(arrAlertFeedItems) {
  3315.         for (var i = 0; i < arrAlertFeedItems.length; i++) {
  3316.             onNewItemCallback.call(onNewItemCallbackThis, arrAlertFeedItems[i]);
  3317.         }
  3318.         this.stopIntervalForFeeds();
  3319.  
  3320.     };
  3321.  
  3322.     this._initFeedsToPoll = function() {
  3323.         var arrFeeds = AlertFeedsDAL.getFeedsToPoll();
  3324.         if (!arrFeeds || arrFeeds.length == 0) return;
  3325.  
  3326.         this._pollFeeds(arrFeeds);
  3327.         var self = this;
  3328.         oTimer = setTimeout(function() { self._initFeedsToPoll(); }, oTimer_IntervalSec * 1000);
  3329.     };
  3330.  
  3331.     this._pollFeeds = function(arrFeedsToPoll) {
  3332.         var strRequestUrl = "";
  3333.         var feed = null;
  3334.         var feedPoller = null;
  3335.         for (var i = 0; i < arrFeedsToPoll.length; i++) {
  3336.             feed = arrFeedsToPoll[i];
  3337.             AlertFeedsDAL.updateFeedLastCheckTime(feed.id);
  3338.             feedPoller = new FeedPoller(feed.url, false, this._onFeedResponse, this, feed);
  3339.         }
  3340.     };
  3341.  
  3342.     this._onFeedResponse = function(objFeedCustomData, feed) {
  3343.         //feeds arrives in last published first - order, reverse it in order to show them ordered by pubDate
  3344.         objFeedCustomData.reverse();
  3345.         var arrUnshownFeedItems = AlertFeedsDAL.saveFeedData(objFeedCustomData, feed.id);
  3346.         if (!arrUnshownFeedItems || arrUnshownFeedItems.length == 0 || !AlertFeedsDAL.isFeedEnabled(feed.id)) return;
  3347.  
  3348.         this._pushNewItems(arrUnshownFeedItems);
  3349.     };
  3350. };
  3351.  
  3352. AlertFeedsManager.prototype = new BaseAlertServerManager();
  3353. function AlertInfoManager(prefs, onChangeCallback, onChangeCallbackThis) {
  3354.     var ALERT_INFO_CHECK_INTERVAL_MIN = 60;
  3355.     var SERVER_URL_POSTFIX = "/Alerts/AlertServices.asmx/GetToolbarAlertsInfo";
  3356.     var oTimer = null;
  3357.     this.prefs = prefs;
  3358.  
  3359.     this.init = function(isForceCheck) {
  3360.         if (isForceCheck) this._nullifyLastCheckTime();
  3361.         this._setCheckTimer();
  3362.     };
  3363.  
  3364.     this.reInit = function(isForceCheck) {
  3365.         this.shutdown();
  3366.         this.init(isForceCheck);
  3367.     };
  3368.  
  3369.     this.shutdown = function() {
  3370.         clearTimeout(oTimer);
  3371.     };
  3372.  
  3373.     this._setCheckTimer = function() {
  3374.         var iNextInfoTimeout = this._getNextCheckInterval();
  3375.         var self = this;
  3376.         oTimer = setTimeout(function() { self._serverRequest(); }, iNextInfoTimeout);
  3377.     };
  3378.  
  3379.     this._nullifyLastCheckTime = function() {
  3380.         prefs.SetPref(AlertPrefConsts.alertInfoLastCheckTime, null);
  3381.     };
  3382.  
  3383.     this._getNextCheckInterval = function() {
  3384.         var strLastCheckTime = prefs.GetPref(AlertPrefConsts.alertInfoLastCheckTime);
  3385.         if (!strLastCheckTime) return 0;
  3386.  
  3387.         var iLastCheckTime = Date.parse(strLastCheckTime);
  3388.         if (!iLastCheckTime) return 0;
  3389.         
  3390.         var iNow = Date.parse(Date());
  3391.  
  3392.         //check interval in ms
  3393.         var iCheckIntervalMS = this._getCheckInterval();
  3394.         var iNextCheckIntervalMS = iLastCheckTime + iCheckIntervalMS - iNow;
  3395.  
  3396.         //next check interval is passed, check immediately
  3397.         if (iNextCheckIntervalMS <= 0)
  3398.             return 0;
  3399.         else
  3400.             return iNextCheckIntervalMS;
  3401.     };
  3402.     
  3403.     this._getCheckInterval = function() {
  3404.         var iCheckInterval = prefs.GetPref(AlertPrefConsts.alertInfoInterval);
  3405.         if (!iCheckInterval) {
  3406.             iCheckInterval = ALERT_INFO_CHECK_INTERVAL_MIN
  3407.             prefs.SetPref(AlertPrefConsts.alertInfoInterval, iCheckInterval);
  3408.         }
  3409.  
  3410.         return iCheckInterval * 60 * 1000;
  3411.     };
  3412.  
  3413.     this._serverRequest = function() {
  3414.         var arrAlertChannels = AlertFeedsDAL.getChannelsArray();
  3415.         if (!arrAlertChannels || arrAlertChannels.length == 0) return;
  3416.  
  3417.         var serviceUrl = this._getFullServerUrl(SERVER_URL_POSTFIX);
  3418.         var self = this;
  3419.         var alertInfoRQ = new AlertInfoRQ(serviceUrl, arrAlertChannels, function(alertInfoRS) { self._serverResponse(alertInfoRS) });
  3420.  
  3421.         //save last check time
  3422.         prefs.SetPref(AlertPrefConsts.alertInfoLastCheckTime, Date());
  3423.  
  3424.         //execute request
  3425.         EBServerDataURL.ServiceRequest(alertInfoRQ);
  3426.     };
  3427.  
  3428.     this._serverResponse = function(strResponse) {
  3429.         var alertInfoRS = new AlertInfoRS(strResponse);
  3430.         this._saveServerResponse(alertInfoRS);
  3431.         
  3432.         //set next check
  3433.         this._setCheckTimer();
  3434.     };
  3435.  
  3436.     this._saveServerResponse = function(alertInfoRS) {
  3437.         prefs.SetPref(AlertPrefConsts.alertInfoInterval, alertInfoRS.interval);
  3438.  
  3439.         //nothing modified
  3440.         if (alertInfoRS.modifiedChannelsArray.length == 0) return;
  3441.         
  3442.         AlertFeedsDAL.updateChannelsAndFeeds(alertInfoRS.modifiedChannelsArray);
  3443.         onChangeCallback.call(onChangeCallbackThis);
  3444.     };
  3445. };
  3446.  
  3447. AlertInfoManager.prototype = new BaseAlertServerManager();
  3448. function AlertLoginManager(prefs) {
  3449.     var LOGIN_CHECK_INTERVAL_MIN = 1440;
  3450.     var SERVER_URL_POSTFIX = "/Alerts/AlertServices.asmx/AlertLogin";
  3451.     var oTimer = null;
  3452.     this.prefs = prefs;
  3453.  
  3454.     this.init = function() {
  3455.         this._setCheckTimer();
  3456.     };
  3457.  
  3458.     this.reInit = function() {
  3459.         this.shutdown();
  3460.         this.init();
  3461.     };
  3462.  
  3463.     this.shutdown = function() {
  3464.         clearTimeout(oTimer);
  3465.     };
  3466.  
  3467.     this._setCheckTimer = function() {
  3468.         var iNextLoginTimeout = this._getNextCheckInterval();
  3469.         var self = this;
  3470.         oTimer = setTimeout(function() { self._serverRequest(); }, iNextLoginTimeout);
  3471.     };
  3472.  
  3473.     this._getCheckInterval = function() {
  3474.         var iCheckInterval = prefs.GetPref(AlertPrefConsts.loginIntervalMin);
  3475.         if (!iCheckInterval) {
  3476.             iCheckInterval = LOGIN_CHECK_INTERVAL_MIN
  3477.             prefs.SetPref(AlertPrefConsts.loginIntervalMin, iCheckInterval);
  3478.         }
  3479.  
  3480.         return iCheckInterval * 60 * 1000;
  3481.     };
  3482.  
  3483.     this._getNextCheckInterval = function() {
  3484.         var strLastCheckTime = prefs.GetPref(AlertPrefConsts.loginLastCheckTime);
  3485.         if (!strLastCheckTime) return 0;
  3486.  
  3487.         var strLastUpdateTime = prefs.GetPref(AlertPrefConsts.loginLastUpdateTime);
  3488.         if (!strLastUpdateTime) return 0;
  3489.  
  3490.         var iLastCheckTime = Date.parse(strLastCheckTime);
  3491.         if (!iLastCheckTime) return 0;
  3492.         
  3493.         var iNow = Date.parse(Date());
  3494.         //check interval in ms
  3495.         var iCheckIntervalMS = this._getCheckInterval();
  3496.         var iNextCheckIntervalMS = iLastCheckTime + iCheckIntervalMS - iNow;
  3497.  
  3498.         //next check interval is passed, check immidiatly
  3499.         if (iNextCheckIntervalMS <= 0)
  3500.             return 0;
  3501.         else
  3502.             return iNextCheckIntervalMS;
  3503.     };
  3504.  
  3505.     this._getUserId = function() {
  3506.         var userId = prefs.GetPref(AlertPrefConsts.userId);
  3507.         if (!userId) {
  3508.             userId = generateGuid();
  3509.             prefs.SetPref(AlertPrefConsts.userId, userId);
  3510.         }
  3511.  
  3512.         return userId;
  3513.     };
  3514.  
  3515.     this._serverRequest = function() {
  3516.         var serviceUrl = this._getFullServerUrl(SERVER_URL_POSTFIX);
  3517.         var lastUpdateTime = prefs.GetPref(AlertPrefConsts.loginLastUpdateTime);
  3518.         if (!lastUpdateTime) lastUpdateTime = 0;
  3519.         var userId = this._getUserId();
  3520.         var alertsStatus = (prefs.GetPref(AlertPrefConsts.alertEnabled) == false) ? "DISABLED" : "ENABLED";
  3521.         var version = "2.5.2.14";
  3522.         var arrChannelsIds = AlertFeedsDAL.getChannelsIdsArray();
  3523.         var self = this;
  3524.         var alertLoginRQ = new AlertLoginRQ(serviceUrl, lastUpdateTime, userId, alertsStatus, version, arrChannelsIds,
  3525.                                 function(strResponse) { self._serverResponse(strResponse) });
  3526.  
  3527.         //save last check time
  3528.         prefs.SetPref(AlertPrefConsts.loginLastCheckTime, Date());
  3529.         //execute the request
  3530.         EBServerDataURL.ServiceRequest(alertLoginRQ);
  3531.     };
  3532.  
  3533.     this._serverResponse = function(strResponse) {
  3534.         var alertLoginRS = new AlertLoginRS(strResponse);
  3535.         if (alertLoginRS.isModified)
  3536.             this._saveServerResponse(alertLoginRS);
  3537.  
  3538.         //set next check
  3539.         this._setCheckTimer();
  3540.     };
  3541.  
  3542.     this._saveServerResponse = function(alertLoginRS) {
  3543.         prefs.SetPref(AlertPrefConsts.loginLastUpdateTime, alertLoginRS.lastUpdateTime);
  3544.         prefs.SetPref(AlertPrefConsts.loginIntervalMin, alertLoginRS.intervalMin);
  3545.         prefs.SetPref(AlertPrefConsts.locale, alertLoginRS.locale);
  3546.         
  3547.         prefs.SetPref(AlertPrefConsts.userCloseIntervalMin, alertLoginRS.data.userCloseIntervalMin);
  3548.         prefs.SetPref(AlertPrefConsts.messageShowTimeSec, alertLoginRS.data.messageShowTimeSec);
  3549.         prefs.SetPref(AlertPrefConsts.showTrayIcon, alertLoginRS.data.showTrayIcon);
  3550.         prefs.SetPref(AlertPrefConsts.servicesServerUrl, alertLoginRS.data.servicesServerUrl);
  3551.         prefs.SetPref(AlertPrefConsts.clientsServerUrl, alertLoginRS.data.clientsServerUrl);
  3552.     };
  3553. };
  3554.  
  3555. AlertLoginManager.prototype = new BaseAlertServerManager();
  3556. function AlertUsageManager(oPrefs) {
  3557.     this.prefs = oPrefs;
  3558.     
  3559.     var urlPostfix = "/Alerts/AlertServices.asmx/SetAlertUsageRequest";
  3560.     
  3561.     this.msgViewed = function(itemGuid, feedId) {
  3562.         if(itemGuid && feedId)
  3563.             this._pushUsage(itemGuid, feedId, "MESSAGE_VIEWED");
  3564.         else
  3565.             this._pushUsage(null, null, "INITIAL_NOTIFICATION_VIEWED");
  3566.     };
  3567.  
  3568.     this.msgClicked = function(itemGuid, feedId) {
  3569.         if(itemGuid && feedId)
  3570.             this._pushUsage(itemGuid, feedId, "CLICK_ON_MESSAGE");
  3571.         else
  3572.             this._pushUsage(null, null, "INITIAL_NOTIFICATION_CLICKED");
  3573.     };
  3574.  
  3575.     this.msgForwarded = function(itemGuid, feedId) {
  3576.         if (itemGuid && feedId)
  3577.             this._pushUsage(itemGuid, feedId, "MESSAGE_PAGED_FORWARD");
  3578.     };
  3579.  
  3580.     this.msgBackwarded = function(itemGuid, feedId) {
  3581.         if (itemGuid && feedId)
  3582.             this._pushUsage(itemGuid, feedId, "MESSAGE_PAGED_BACKWARD");
  3583.     };
  3584.  
  3585.     this._pushUsage = function(itemGuid, feedId, type) {
  3586.         var channelId = (itemGuid && feedId) ?
  3587.             AlertFeedsDAL.getFirstChannelByFeedId(feedId) :
  3588.             AlertFeedsDAL.getFirstChannel(feedId);
  3589.  
  3590.         var fullUrl = this._getFullServerUrl(urlPostfix);
  3591.         var oMsg = new AlertUsageRQ(fullUrl, type, channelId, feedId, itemGuid, null)
  3592.         EBServerDataURL.ServiceRequest(oMsg);
  3593.     };
  3594. };
  3595.  
  3596. AlertUsageManager.prototype = new BaseAlertServerManager();
  3597. function BaseAlertManager() {
  3598.     this.isInit = function() { };
  3599.     this.register = function(strOriginalCTID) { return true; };
  3600.     this.unregister = function(strOriginalCTID) { };
  3601.     this.replaceAlertChannels = function(strSource, arrAlertChannels) { };
  3602.     this.addAlertChannels = function(strSource, arrAlertChannels) { };
  3603.     this.addMyStuffAlertChannels = function(strSource, arrAlertChannels, providerName) { };
  3604.     this.openSettingsDialog = function(strOriginalCTID, win) { };
  3605.     this.refresh = function() { };
  3606.     this.alertEnabled = function(value) { }; //get, set
  3607.     this.sendInternalAlert = function(alertItem) { };
  3608. };
  3609. function BaseAlertServerManager() {
  3610.     this.prefs = null;
  3611.  
  3612.     this._getFullServerUrl = function(strPostfix) {
  3613.         var strBaseServerUrl = this.prefs.GetPref(AlertPrefConsts.servicesServerUrl);
  3614.         if (!strBaseServerUrl) {
  3615.             strBaseServerUrl = AlertConsts.servicesBaseUrl;
  3616.             this.prefs.SetPref(AlertPrefConsts.servicesServerUrl, strBaseServerUrl);
  3617.         }
  3618.  
  3619.         return strBaseServerUrl + strPostfix;
  3620.     };
  3621.  
  3622.     this._getArrayOfIds = function(hashObjects) {
  3623.         var arrIds = new Array();
  3624.         for (var i = 0; i < this.hashObjects.Count(); arrIds.push(this.hashObjects.GetByIndex(i)), i++);
  3625.         return arrIds;
  3626.     };
  3627. };
  3628. function ExternalAlertManager() {
  3629.      var alertXPCOM = null;
  3630.  
  3631.     this.register = function(strOriginalCTID) {
  3632.     if (alertXPCOM == null) return;
  3633.         
  3634.         try {
  3635.             alertXPCOM.register(strOriginalCTID);
  3636.         }
  3637.         catch (ex) { }
  3638.     };
  3639.  
  3640.     this.unregister = function(strOriginalCTID) {
  3641.         alertXPCOM.unregister(strOriginalCTID);
  3642.     };
  3643.  
  3644.     this.replaceAlertChannels = function(strOriginalCTID, arrChannelIds) {
  3645.         alertXPCOM.replaceChannels(strOriginalCTID, arrChannelIds);
  3646.     };
  3647.  
  3648.     this.addAlertChannels = function(strSource, arrChannelsIds) {
  3649.         alertXPCOM.addChannels(strSource, arrChannelsIds);
  3650.     };
  3651.  
  3652.     this.addMyStuffAlertChannels = function(strSource, arrChannelsIds, providerName) {
  3653.         alertXPCOM.addMyStuffChannels(strSource, arrChannelsIds[0], providerName);
  3654.         try {
  3655.             alertXPCOM.showTrayIcon(true);
  3656.         }
  3657.         catch (ex) {
  3658.             Logging.LogToConsole(ex);
  3659.         }
  3660.     };
  3661.  
  3662.     this.openSettingsDialog = function(strOriginalCTID) {
  3663.         alertXPCOM.openSettingsDialog(strOriginalCTID);
  3664.     };
  3665.  
  3666.     this.refresh = function() {
  3667.         alertXPCOM.refresh();
  3668.     };
  3669.  
  3670.     this.alertEnabled = function(value) {
  3671.         var strRegKey = (AppInfo.isVista()) ? "Software\\AppDataLow\\Software\\Conduit\\Community Alerts\\Settings" :
  3672.                                             "Software\\Conduit\\Community Alerts\\Settings";
  3673.         //get
  3674.         if (typeof value == "undefined") {
  3675.             try {
  3676.                 var bEnabled = alertXPCOM.isAlertsEnabled();
  3677.                 return bEnabled;
  3678.             }
  3679.             //old IE alert
  3680.             catch (ex) {
  3681.                 var regValue = RegistryManager.GetRegistryEntry(RegistryManager.HKEY_CURRENT_USER, strRegKey, "ShowAlerts");
  3682.                 return (regValue) ? regValue.charAt(0).toString().toUpperCase() == "T" : true;
  3683.             }
  3684.         }
  3685.         //set
  3686.         else {
  3687.             try {
  3688.                 alertXPCOM.enableAlerts(value);
  3689.             }
  3690.             //old IE alert
  3691.             catch (ex) {
  3692.                 RegistryManager.WriteRegistryEntry(RegistryManager.HKEY_CURRENT_USER, strRegKey, "ShowAlerts", "TRUE");
  3693.             }
  3694.         }
  3695.     };
  3696.  
  3697.     this.sendInternalAlert = function(alertItem) {
  3698.         var strAlertXml = alertItem.toXMLString();
  3699.         try {
  3700.             alertXPCOM.sendInternalAlert(strAlertXml);
  3701.         }
  3702.         catch (ex) { EBLog(ex); }
  3703.     };
  3704.  
  3705.     this.isInit = function() {
  3706.         return (alertXPCOM && alertXPCOM.isInit());
  3707.     };
  3708.  
  3709.     this._init = function() {
  3710.         try {
  3711.             alertXPCOM = Components.classes["@conduit.com/externalAlert;3"].getService(Components.interfaces.IFFExternalAlert3);
  3712.         }
  3713.         catch (ex) {
  3714.             EBLog(ex);
  3715.             alertXPCOM = null;
  3716.         }
  3717.     };
  3718.  
  3719.     this._init();
  3720. };
  3721.  
  3722. ExternalAlertManager.prototype = new BaseAlertManager();
  3723. ///<reference path="..\..\DAL\ChatProviderRoomInfo.js" />
  3724. function InternalAlertManager() {
  3725.     var prefs = new PrefManager(AlertPrefConsts.prefix, AlertPrefConsts.prefix);
  3726.     var loginManager = null;
  3727.     var alertInfoManager = null;
  3728.     var feedManager = null;
  3729.     var hashChannels = null;
  3730.     var hashFeeds = null;
  3731.     var trayIconShown = false;
  3732.     this.uiManager = null;
  3733.     this.usageManager = null;
  3734.     var initTimeStamp = Date.parse(Date());
  3735.     var arrWaitingMessages = new Array();
  3736.     var msgsWaitingList = new Array();
  3737.     var isFirstMsgSent = false;
  3738.     var publisherAlertHtml = '<div style="padding:3px 0px 0px 0px; height: 65px; overflow: hidden !important;"><div style="font-family:Arial; font-size: 9px; color: #7c99c5; margin-bottom:2px;">{0}</div><div style="color: rgb(0,82,170); font-family:Arial; font-size: 13px; margin-top:2px; padding:0px;">{1}</div><div style="font-family:Arial; font-size: 11px; margin:2px 1px 0px 1px;">{2}</div></div>';
  3739.     var publisherAlertHtmlLinux = '<div style="padding:3px 0px 0px 0px; height: 65px; overflow: hidden !important;"><div style="font-family:Arial; font-size: 9px; color: #7c99c5; margin-bottom:2px;">{0}</div><div style="color: rgb(0,82,170); font-family:Arial; font-size: 12px; margin-top:2px; padding:0px;">{1}</div><div style="font-family:Arial; font-size: 10px; margin:2px 1px 0px 1px;">{2}</div></div>';
  3740.     var isInIdle = false;
  3741.     var feedItemsHash = new HashArray();
  3742.     this.register = function(strOriginalCTID) {
  3743.         AlertFeedsDAL.registerSource(strOriginalCTID);
  3744.         return true;
  3745.     };
  3746.  
  3747.     this.unregister = function(strOriginalCTID) {
  3748.         AlertFeedsDAL.unregisterSource(strOriginalCTID);
  3749.         if (AlertFeedsDAL.getRegisteredSourcesCount() == 0)
  3750.             this._cleanUpAllData();
  3751.     };
  3752.  
  3753.     this.replaceAlertChannels = function(strSource, arrAlertChannels) {
  3754.         var bIsNew = AlertFeedsDAL.replaceAlertChannels(strSource, arrAlertChannels);
  3755.         if (bIsNew && alertInfoManager && this.alertEnabled())
  3756.             alertInfoManager.reInit(true);
  3757.     };
  3758.  
  3759.     this.addAlertChannels = function(strSource, arrAlertChannels) {
  3760.         AlertFeedsDAL.addAlertChannels(strSource, arrAlertChannels);
  3761.         if (alertInfoManager && this.alertEnabled())
  3762.             alertInfoManager.reInit(true);
  3763.  
  3764.         //set icon visible
  3765.         this.showTray(true);
  3766.     };
  3767.  
  3768.     this.addMyStuffAlertChannels = function(strSource, arrAlertChannels, providerName) {
  3769.         this.addAlertChannels(strSource, arrAlertChannels);
  3770.         this._sendSampleAlert(providerName);
  3771.     };
  3772.  
  3773.     this.openSettingsDialog = function(strOriginalCTID, win) {
  3774.         this.uiManager.openSettingsDialog(win);
  3775.     };
  3776.  
  3777.     this.refresh = function() {
  3778.         if (this.alertEnabled()) {
  3779.             AlertFeedsDAL.refresh();
  3780.             alertInfoManager.reInit(true);
  3781.         }
  3782.     };
  3783.  
  3784.     this.onWindowLoad = function(document) {
  3785.         this.uiManager.showHideTray(this.showTray(), document);
  3786.     };
  3787.  
  3788.     //settings methods
  3789.     this.getFeedsHash = function() {
  3790.         var hashFeeds = AlertFeedsDAL.getFeedsSortedHashArray();
  3791.         var hashFeedItems = AlertFeedsDAL.getFeedItemsHash();
  3792.         if (!hashFeeds || hashFeeds.Count() == 0)
  3793.             return hashFeeds;
  3794.  
  3795.         var feed = null;
  3796.         for (var i = 0; i < hashFeeds.Count(); i++) {
  3797.             feed = hashFeeds.GetByIndex(i);
  3798.             if (hashFeedItems.Contains(feed.id))
  3799.                 feed.feedItems = hashFeedItems.GetByID(feed.id);
  3800.         }
  3801.  
  3802.         return hashFeeds;
  3803.     };
  3804.  
  3805.     this.removeShownMessages = function(arrShownMessagesGuids, oFirstTimeMsg) {
  3806.         this.uiManager.alertOpenState = 0;
  3807.         if (oFirstTimeMsg) {
  3808.             //update DB
  3809.             AlertFeedsDAL.updateShownFeedItems(arrShownMessagesGuids);
  3810.             //restart alert open interval
  3811.             feedManager.startIntervalForFeeds();
  3812.             feedItemsHash.Clear();
  3813.         }
  3814.         //first time message was shown
  3815.         else {
  3816.             var that = this;
  3817.             this.uiManager.firstTimeMsg = null;
  3818.             prefs.SetPref(AlertPrefConsts.firstTimeAlertShown, true);
  3819.             setTimeout(function() { that.invokeMsgsWaitList(); }, AlertConsts.messageAfterFirstTimeAlert);
  3820.         }
  3821.     };
  3822.  
  3823.     this.invokeMsgsWaitList = function() {
  3824.         for (var i = 0; i < msgsWaitingList.length; i++)
  3825.             this.sendInternalAlert(msgsWaitingList[i]);
  3826.  
  3827.         msgsWaitingList = new Array();
  3828.     };
  3829.  
  3830.     //update feeds from settings dialog
  3831.     this.updateFeedsFromSettings = function(arrFeeds) {
  3832.         if (!arrFeeds || arrFeeds.length == 0) return;
  3833.  
  3834.         var arrFeedsIds = new Array();
  3835.         for (var i = 0; i < arrFeeds.length; i++)
  3836.             arrFeedsIds.push(arrFeeds[i].id);
  3837.  
  3838.         AlertFeedsDAL.reverseFeedsEnableState(arrFeedsIds);
  3839.  
  3840.         setTimeout(function() { feedManager.initFeedsToShow(); }, 1000);
  3841.     };
  3842.  
  3843.     this.alertEnabled = function(bValue) {
  3844.         //get
  3845.         if (typeof bValue == "undefined") {
  3846.             return (prefs.GetPref(AlertPrefConsts.alertEnabled) == false) ? false : true;
  3847.         }
  3848.         //set
  3849.         else {
  3850.             prefs.SetPref(AlertPrefConsts.alertEnabled, bValue);
  3851.             if (bValue)
  3852.                 this._enable();
  3853.             else
  3854.                 this._disable();
  3855.         }
  3856.     };
  3857.  
  3858.     this.showTray = function(bValue) {
  3859.         //get
  3860.         if (typeof bValue == "undefined")
  3861.             return (prefs.GetPref(AlertPrefConsts.showTrayIcon) == true) ? true : false;
  3862.         //set
  3863.         else {
  3864.             prefs.SetPref(AlertPrefConsts.showTrayIcon, bValue);
  3865.             this.uiManager.showHideTray(bValue);
  3866.         }
  3867.     };
  3868.  
  3869.     this.onIdle = function() {
  3870.         if (!this.alertEnabled()) return;
  3871.         isInIdle = true;
  3872.         feedManager.shutdown();
  3873.     };
  3874.  
  3875.     this.onBackFromIdle = function() {
  3876.         if (!this.alertEnabled()) return;
  3877.         isInIdle = false;
  3878.         this.invokeMsgsWaitList();
  3879.         feedManager.init();
  3880.     };
  3881.  
  3882.     this._cleanUpAllData = function() {
  3883.         AlertFeedsDAL.unlink();
  3884.     };
  3885.  
  3886.     this.onChannelsAndFeedsChange = function() {
  3887.         feedManager.reInit();
  3888.     };
  3889.  
  3890.     this.sendAlert = function(alertItem) {
  3891.         if (this.isFirstMsgShown() && !isInIdle) {
  3892.             if (this._canBroadcastToUI())
  3893.                 this.uiManager.addFeedMessage(alertItem);
  3894.             else {
  3895.                 if (arrWaitingMessages.length == 0)
  3896.                     this._initReleaseWaitingMessages();
  3897.                 arrWaitingMessages.push(alertItem);
  3898.  
  3899.             }
  3900.         }
  3901.         else {
  3902.             msgsWaitingList.push(alertItem);
  3903.             if (!isFirstMsgSent) {
  3904.                 this.uiManager._showFirstTimeAlert(this.createFirstMsgAlertItem(alertItem));
  3905.                 isFirstMsgSent = true;
  3906.             }
  3907.         }
  3908.     };
  3909.  
  3910.     this.onNewFeedAlert = function(feedItem) {
  3911.         var alertItem = this.convertFromFeedToItem(feedItem, false);
  3912.         if (!feedItemsHash.Contains(alertItem.guid)) {
  3913.             this.sendAlert(alertItem);
  3914.             feedItemsHash.Add(alertItem.guid, true);
  3915.         }
  3916.     };
  3917.    
  3918.     this.isFirstMsgShown = function() {
  3919.         return prefs.GetPref(AlertPrefConsts.firstTimeAlertShown);
  3920.     };
  3921.  
  3922.     this.createFirstMsgAlertItem = function(item) {
  3923.         var oAlertMsg = new AlertFeedItem();
  3924.         oAlertMsg.init(this.uiManager.firstTimeMsgTitle, this.uiManager.getFaqLink(), this.uiManager.firstTimeMsgDescription, "", "", "", item.headerImg, null);
  3925.         return this.convertFromFeedToItem(oAlertMsg, true);
  3926.     };
  3927.  
  3928.     this.convertFromFeedToItem = function(feed, firstTime) {
  3929.         var headerCssStyle = { "color": "#004498", "fontFamily": "Arial", "isBold": true };
  3930.         var strTitle = (feed.link) ? stringFormat("<a href=\"{0}\" style=\"text-decoration:underline;\">{1}</a>", feed.link, feed.title) : feed.title;
  3931.         var pubAlertHtml = (AppInfo.OS == AppInfo.LINUX) ? publisherAlertHtmlLinux : publisherAlertHtml;
  3932.         var html = stringFormat(pubAlertHtml, feed.feedTitle, strTitle, feed.description.replace(/\n/, "<br />"));
  3933.         return new AlertItem(feed.headerText, headerCssStyle, feed.headerImage, html, feed.sendUsage, feed.guid, firstTime, feed.feedId);
  3934.     };
  3935.  
  3936.     this.sendInternalAlert = function(alertItem) {
  3937.         if (this.uiManager.alertOpenState == 0)
  3938.             feedManager.initFeedsToShow();
  3939.         
  3940.         this.sendAlert(alertItem);
  3941.     };
  3942.  
  3943.     this._canBroadcastToUI = function() {
  3944.     var now = Date.parse(Date());
  3945.         var bValue = (now - initTimeStamp >= AlertConsts.firstMessageDelayMs);
  3946.         return bValue;
  3947.     };
  3948.  
  3949.     this._initReleaseWaitingMessages = function() {
  3950.         var that = this;
  3951.         var releaseWaitingMessages = function() {
  3952.             if (arrWaitingMessages.length == 0) return;
  3953.  
  3954.             for (var i = 0; i < arrWaitingMessages.length; i++)
  3955.                 that.uiManager.addFeedMessage(arrWaitingMessages[i]);
  3956.  
  3957.             arrWaitingMessages = null;
  3958.         }
  3959.  
  3960.         setTimeout(releaseWaitingMessages, AlertConsts.firstMessageDelayMs);
  3961.     };
  3962.  
  3963.     this._enable = function() {
  3964.         if (!alertInfoManager) alertInfoManager = new AlertInfoManager(prefs, this.onChannelsAndFeedsChange, this);
  3965.         if (!feedManager) feedManager = new AlertFeedsManager(this.onNewFeedAlert, this);
  3966.  
  3967.         var bForceInit = (AlertFeedsDAL.getChannelsIdsArray().length > 0 && !AlertFeedsDAL.isFeedsExists()) ? true : false;
  3968.         alertInfoManager.init(bForceInit);
  3969.         feedManager.init();
  3970.         //change tray icon
  3971.         this.uiManager.onEnable();
  3972.     };
  3973.  
  3974.     this._disable = function() {
  3975.         if (alertInfoManager) alertInfoManager.shutdown();
  3976.         if (feedManager) feedManager.shutdown();
  3977.  
  3978.         //change tray icon
  3979.         this.uiManager.onDisable();
  3980.     };
  3981.  
  3982.     this._sendSampleAlert = function(strTitle) {
  3983.         var oFeedItem = new AlertFeedItem();
  3984.         oFeedItem.feedId = -1;
  3985.         oFeedItem.headerText = "Thanks for adding our Alerts";
  3986.         oFeedItem.feedTitle = strTitle;
  3987.         oFeedItem.title = "The Alerts look like this";
  3988.         oFeedItem.headerImage = "";
  3989.         oFeedItem.sendUsage = false;
  3990.         oFeedItem.description = "They bring community news right to your desktop!";
  3991.         this.onNewFeedAlert(oFeedItem);
  3992.     };
  3993.  
  3994.     this.init = function() {
  3995.         AlertFeedsDAL.init();
  3996.  
  3997.         //always start login manager, even if alert is disbaled
  3998.         var bIsEnabled = this.alertEnabled();
  3999.         loginManager = new AlertLoginManager(prefs);
  4000.         loginManager.init();
  4001.         this.uiManager = new AlertUIManager(prefs, this.onIdle, this.onBackFromIdle, this);
  4002.         this.usageManager = new AlertUsageManager(prefs);
  4003.  
  4004.         if (bIsEnabled)
  4005.             this._enable();
  4006.         else
  4007.             this.uiManager.onDisable();
  4008.     };
  4009. };
  4010.  
  4011. InternalAlertManager.prototype = new BaseAlertManager();
  4012. function AlertInfoRQ(serviceUrl, arrAlertChannels, objCallback) {
  4013.     var ALERT_RQ = "alertInfoRequestXml=<ALERT_XML><TYPE>ALERT_INFO</TYPE><MESSAGE>{0}</MESSAGE></ALERT_XML>";
  4014.     this.callback = objCallback;
  4015.     this.url = serviceUrl;
  4016.     this.postParams = "";
  4017.  
  4018.     this._getChannelsInfo = function(arrAlertChannels) {
  4019.         var strChannelsInfo = "";
  4020.         var strChannelInfo = "";
  4021.         for (var i = 0; i < arrAlertChannels.length; i++) {
  4022.             strChannelInfo = XML.CreateXmlNodeString("ID", arrAlertChannels[i].id);
  4023.             strChannelInfo += XML.CreateXmlNodeString("LAST_UPDATE_TIME", arrAlertChannels[i].lastUpdateTime);
  4024.             strChannelsInfo += XML.CreateXmlNodeString("ALERT_CHANNEL", strChannelInfo);
  4025.         }
  4026.  
  4027.         return strChannelsInfo;
  4028.     };
  4029.  
  4030.     this._init = function() {
  4031.         var strChannelsInfo = this._getChannelsInfo(arrAlertChannels);
  4032.         this.postParams = stringFormat(ALERT_RQ, strChannelsInfo);
  4033.     };
  4034.     
  4035.     this._init();
  4036. };
  4037. function AlertInfoRS(strResponseXml) {
  4038.     this.interval = 0;
  4039.     this.modifiedChannelsArray = new Array()
  4040.  
  4041.     this._parseChannels = function(xmlChannels) {
  4042.         if (!xmlChannels) return;
  4043.  
  4044.         var xmlChannel = null;
  4045.         var xmlFeeds = null;
  4046.         var xmlFeed = null;
  4047.         var channel = null;
  4048.         var feed = null;
  4049.  
  4050.         for (var i = 0; i < xmlChannels.childNodes.length; i++) {
  4051.             xmlChannel = xmlChannels.childNodes[i];
  4052.             if (xmlChannel.tagName == "CHANNEL") {
  4053.                 channel = new AlertChannel();
  4054.                 channel.initFromXml(xmlChannel);
  4055.                 if (channel.isModified) {
  4056.                     this.modifiedChannelsArray.push(channel);
  4057.                     channel.feeds = new Array();
  4058.                     
  4059.                     xmlFeeds = XML.SelectSingleNode(xmlChannel, "FEEDS");
  4060.                     for (var j = 0; j < xmlFeeds.childNodes.length; j++) {
  4061.                         xmlFeed = xmlFeeds.childNodes[j];
  4062.  
  4063.                         if (xmlFeed.tagName == "FEED") {
  4064.                             feed = new AlertFeed();
  4065.                             feed.initFromXml(xmlFeed, channel.id);
  4066.                             channel.feeds.push(feed);
  4067.                         }
  4068.                     }
  4069.                 }
  4070.             }
  4071.         }
  4072.     };
  4073.     
  4074.     this._init = function() {
  4075.         if (!strResponseXml) return;
  4076.  
  4077.         var xmlResponse = XML.GetXmlDocument(strResponseXml);
  4078.         if (!xmlResponse) return;
  4079.  
  4080.         this.interval = XML.GetSingleNodeValueAsInteger(xmlResponse, "INTERVAL");
  4081.         var xmlChannels = XML.SelectSingleNode(xmlResponse, "CHANNELS");
  4082.         this._parseChannels(xmlChannels);
  4083.     };
  4084.  
  4085.     this._init();
  4086. };
  4087. function AlertLoginRQ(serviceUrl, lastUpdateTime, userId, alertsStatus, version, arrChannels, objCallback) {
  4088.     var ALERT_RQ = "alertLoginRequestXml=<ALERT_XML><TYPE>ALERT_LOGIN</TYPE><MESSAGE><LUT>{0}</LUT><USER_ID>{1}</USER_ID><USER_ALERTS_STATUS>{2}</USER_ALERTS_STATUS><VERSION>{3}</VERSION><CHANNELS>{4}</CHANNELS></MESSAGE></ALERT_XML>";
  4089.  
  4090.     this.callback = objCallback;
  4091.     this.url = serviceUrl;
  4092.     this.postParams = "";
  4093.  
  4094.     this._generateChannelsInfo = function(arrChannels) {
  4095.         var strChannels = "<ID>" + arrChannels.join("</ID><ID>") + "</ID>";
  4096.         return strChannels;
  4097.     };
  4098.     
  4099.     this._init = function() {
  4100.     var strChannelsInfo = this._generateChannelsInfo(arrChannels);
  4101.         this.postParams = stringFormat(ALERT_RQ, lastUpdateTime, userId, alertsStatus, version, strChannelsInfo);
  4102.     };
  4103.     
  4104.     this._init();
  4105. };
  4106.  
  4107. AlertLoginRQ.prototype = new BaseServerRequest();
  4108. function AlertLoginRS(strResponseXml) {
  4109.     var FLAG_NOT_MOFIFIED = "NOT_MODIFIED";
  4110.     this.isModified = true;
  4111.     this.lastUpdateTime = "";
  4112.     this.intervalMin = 0;
  4113.     this.locale = "";
  4114.     this.data = null;
  4115.  
  4116.     this._init = function() {
  4117.         if (!strResponseXml) return;
  4118.  
  4119.         var xmlResponse = XML.GetXmlDocument(strResponseXml);
  4120.         if (!xmlResponse) return;
  4121.  
  4122.         var flag = XML.GetSingleNodeValue(xmlResponse, "FLAGS");
  4123.         if (flag == FLAG_NOT_MOFIFIED) {
  4124.             this.isModified = false;
  4125.             return;
  4126.         }
  4127.  
  4128.         this.lastUpdateTime = XML.GetSingleNodeValue(xmlResponse, "LUT");
  4129.         this.intervalMin = XML.GetSingleNodeValueAsInteger(xmlResponse, "INTERVAL_MM");
  4130.         this.locale = XML.GetSingleNodeValue(xmlResponse, "LOCALE");
  4131.         this.data = new AlertLoginRSData(XML.SelectSingleNode(xmlResponse, "DATA"));
  4132.     };
  4133.  
  4134.     this._init();
  4135. };
  4136.  
  4137. function AlertLoginRSData(xmlData) {
  4138.     this.userCloseIntervalMin = 0;
  4139.     this.messageShowTimeSec = 0;
  4140.     this.showTrayIcon = null;
  4141.     this.servicesServerUrl = "";
  4142.     this.clientsServerUrl = "";
  4143.     
  4144.     this._init = function()
  4145.     {
  4146.         if(!xmlData) return;
  4147.  
  4148.         this.userCloseIntervalMin = XML.GetSingleNodeValueAsInteger(xmlData, "USER_CLOSE_INTERVAL_MM");
  4149.         this.messageShowTimeSec = XML.GetSingleNodeValueAsInteger(xmlData, "MESSAGE_SHOW_TIME_SS");
  4150.         this.showTrayIcon = XML.GetSingleNodeValueAsBoolean(xmlData, "SHOW_SYS_TRAY_ICON");
  4151.         this.servicesServerUrl = XML.GetSingleNodeValue(xmlData, "ALP_SERVICES_SERVER_URL");
  4152.         this.clientsServerUrl = XML.GetSingleNodeValue(xmlData, "ALP_CLIENTS_SERVER_URL");
  4153.     };
  4154.     
  4155.     this._init();
  4156. };
  4157. function AlertUsageRQ(serviceUrl, type, channelId, feedId, itemId ,objCallback) {
  4158.     var ALERT_RQ = "alertUsageRequestXml=<ALERT_XML><TYPE>ALERT_USAGE</TYPE><MESSAGE><VERSION>2.5.2.14</VERSION><TYPE>{0}</TYPE><DATA><ALERT_ID>{1}</ALERT_ID>{2}</DATA></MESSAGE></ALERT_XML>";
  4159.     var FEED_ITEM_INFO = "<FEED_ID>{0}</FEED_ID><ITEM_ID>{1}</ITEM_ID>";
  4160.     this.callback = objCallback;
  4161.     this.url = serviceUrl;
  4162.     this.postParams = "";
  4163.  
  4164.     this._init = function() {
  4165.         var feedChannelInfo = (feedId && itemId) ?
  4166.                                 stringFormat(FEED_ITEM_INFO, feedId, itemId) : "";
  4167.         this.postParams = stringFormat(ALERT_RQ, type, channelId, feedChannelInfo);
  4168.     };
  4169.  
  4170.     this._init();
  4171. };
  4172. function AlertUIManager(prefs, onIdle, onBackFromIdle, objThis) {
  4173.     var alertWidth = "313";
  4174.     var alertHeigth = "133";
  4175.     var alertWindowType = "EBAlertMainType";
  4176.     var alertWindowName = "EBAlertMainName";
  4177.  
  4178.     var settingsWindowType = "EBAlertSettingsType";
  4179.     var settingsWindowName = "EBAlertSettingsName";
  4180.  
  4181.     var aboutWindowType = "EBAlertAboutType";
  4182.     var aboutWindowName = "EBAlertAboutName";
  4183.  
  4184.     var previewWindowType = "EBAlertPreviewType";
  4185.     var previewWindowName = "EBAlertPreviewType";
  4186.  
  4187.     //links postfix urls
  4188.     var linkFeedback = "Alerts/Feedback/?aid=";
  4189.     var linkFaq = "Alerts/Faq/?aid=";
  4190.     var linkPrivacy = "Alerts/Privacy/?aid=";
  4191.     
  4192.     //tray icon
  4193.     var iconPanelId = "pnl_CT2384137_Alert";
  4194.     var iconId = "icon_CT2384137_Alert";
  4195.     var ringIconUrl = "chrome://iobitcom/skin/alert/TrayIconAnimated.gif";
  4196.     var alertIconUrl = "chrome://iobitcom/skin/alert/TrayIcon.ico";
  4197.     var disabledIconUrl = "chrome://iobitcom/skin/alert/TrayIconBlocked.ico";
  4198.     var currentIconUrl = "";
  4199.     
  4200.     var arrFeedMessages = new Array();
  4201.     var arrWaitingMessagesFF2 = new Array();
  4202.     var tryNotifyLoops = 10;
  4203.     var idleObserver;
  4204.     var idleTimeout = 60; //sec
  4205.     this.firstTimeMsgTitle = "Introducing a handy new feature";
  4206.     this.firstTimeMsgDescription = "As a community toolbar user, you're about to receive\nimportant news from us in an alert like this one.";
  4207.     this.alertOpenState = 0;
  4208.     var bShowFirstTime = true; //in order not to show first time message more then once (happends when after installation there are more then one alert)
  4209.     var oPopup = null;
  4210.     var lastActiveElement = null;
  4211.     var lastActiveElementWindow = null;
  4212.     var firstTimeMsg = null;
  4213.  
  4214.     this.observer = new Object();
  4215.     this.observer.topic = "eb-alert-new-message";
  4216.  
  4217.     this.addFeedMessage = function(objAlertItem) {
  4218.         arrFeedMessages.push(objAlertItem);
  4219.         this._showAlert(objAlertItem);
  4220.     };
  4221.  
  4222.     this.getFeedMessages = function() {
  4223.         return arrFeedMessages;
  4224.     };
  4225.  
  4226.     this.getFirstTimeMsg = function() {
  4227.         return firstTimeMsg;
  4228.     };
  4229.  
  4230.     this.openAlertDialog = function(oAlertMsg) {
  4231.         var win = getWindow();
  4232.         var oPos = this._getMainDialogPosition(win);
  4233.  
  4234.         //FF3+ alert is <panel noautofocus="true" />
  4235.         if (AppInfo.isGecko19 && AppInfo.OS != AppInfo.LINUX) {
  4236.             this.alertOpenState = 2;
  4237.             oPopup = win.document.getElementById("alertMain_CT2384137");
  4238.             oPopup.openPopupAtScreen(oPos.x, oPos.y, false);
  4239.             oPopup.addAlert(oAlertMsg);
  4240.         }
  4241.         //FF2 alert is xul dialog, that returns focus after load.
  4242.         else {
  4243.             this.alertOpenState = 1;
  4244.             lastActiveElement = win.document.commandDispatcher.focusedElement;
  4245.             lastActiveElementWindow = win;
  4246.  
  4247.             var strParams = stringFormat("chrome,dependent,resizeable=no,titlebar=yes,top={0},left={1}", oPos.y, oPos.x);
  4248.             oPopup = win.openDialog(AlertConsts.mainDialogPath, alertWindowName, strParams, oAlertMsg);
  4249.         }
  4250.     };
  4251.  
  4252.     this.openSettingsDialog = function(win) {
  4253.         if (!win) win = getWindow();
  4254.         var strParams = "chrome,dependent,modal,resizeable=no,titlebar=yes,centerscreen";
  4255.         win.openDialog(AlertConsts.settingsDialogPath, settingsWindowName, strParams);
  4256.     };
  4257.  
  4258.     this.openAboutDialog = function(win) {
  4259.         if (!win) win = getWindow();
  4260.         var strParams = "chrome,dependent,modal,resizeable=no,titlebar=yes,centerscreen";
  4261.         win.openDialog(AlertConsts.aboutDialogPath, aboutWindowName, strParams);
  4262.     };
  4263.  
  4264.     this.openPreviewDialog = function(feed, win) {
  4265.         var strParams = "chrome,dependent,modal,resizeable=no,titlebar=yes,centerscreen";
  4266.         win.openDialog(AlertConsts.channelMessagesPreviewDialogPath, previewWindowName, strParams, feed);
  4267.     };
  4268.  
  4269.     this.showHideTray = function(bValue, document) {
  4270.         var strDisplay = (bValue) ? "" : "none";
  4271.  
  4272.         this._setTrayIcon(currentIconUrl, document);
  4273.         
  4274.         //set to single window
  4275.         if (document)
  4276.             document.getElementById(iconPanelId).style.display = strDisplay;
  4277.         //set to all windows
  4278.         else {
  4279.             var arrWindows = getWindows();
  4280.             for (var i = 0; i < arrWindows.length; i++)
  4281.                 arrWindows[i].document.getElementById(iconPanelId).style.display = strDisplay;
  4282.         }
  4283.     };
  4284.  
  4285.     this.returnFocus = function() {
  4286.         //do not return focus in mac, because the alert window is goind under the main window.
  4287.         if (!lastActiveElement || !lastActiveElementWindow || AppInfo.OS == AppInfo.MAC) return;
  4288.  
  4289.         try {
  4290.             lastActiveElementWindow.focus();
  4291.             lastActiveElement.focus();
  4292.         }
  4293.         catch (ex) {
  4294.             Logging.LogToConsole(ex);
  4295.         }
  4296.     };
  4297.  
  4298.     this.releaseFF2WaitingMessages = function() {
  4299.         if (arrWaitingMessagesFF2.length == 0) return;
  4300.         this.alertOpenState = 2;
  4301.  
  4302.         for (var i = 0; i < arrWaitingMessagesFF2.length; i++)
  4303.             this._showAlert(arrWaitingMessagesFF2[i]);
  4304.  
  4305.         arrWaitingMessagesFF2 = new Array();
  4306.     };
  4307.     
  4308.     this.onEnable = function() {
  4309.         currentIconUrl = alertIconUrl;
  4310.         this._setTrayIcon(alertIconUrl);
  4311.     };
  4312.  
  4313.     this.onDisable = function() {
  4314.         currentIconUrl = disabledIconUrl;
  4315.         this._setTrayIcon(disabledIconUrl);
  4316.     };
  4317.  
  4318.     this.setAnimatedIcon = function() {
  4319.         this._setTrayIcon(ringIconUrl);
  4320.     };
  4321.  
  4322.     this.setNormalIcon = function() {
  4323.         this.onEnable();
  4324.     };
  4325.  
  4326.     this.getFeedBackLink = function() {
  4327.         return this._getLinkUrl(linkFeedback);
  4328.     };
  4329.  
  4330.     this.getFaqLink = function() {
  4331.         return this._getLinkUrl(linkFaq);
  4332.     };
  4333.  
  4334.     this.getPrivacyLink = function() {
  4335.         return this._getLinkUrl(linkPrivacy);
  4336.     };
  4337.  
  4338.     this.onIdle = function(iIdleTime) {
  4339.         onIdle.call(objThis);
  4340.     };
  4341.  
  4342.     this.onBackFromIdle = function(iIdleTime) {
  4343.         onBackFromIdle.call(objThis);
  4344.     };
  4345.  
  4346.     this._showFirstTimeAlert = function(item) {
  4347.         arrFeedMessages.push(item);
  4348.         bShowFirstTime = false;
  4349.         this._showAlert(item);
  4350.     };
  4351.     
  4352.     //opens a new dialog or adds to existing if there are messages
  4353.     this._showAlert = function(oAlertMsg) {
  4354.         if (arrFeedMessages.length == 0 || !this._isToShowAlert()) return;
  4355.         switch (this.alertOpenState) {
  4356.             case 0: this.openAlertDialog(oAlertMsg); break;
  4357.             case 1: arrWaitingMessagesFF2.push(oAlertMsg); break;
  4358.             case 2:
  4359.                 //FF3+ - simply activate alert popup's function
  4360.                 if (AppInfo.isGecko19 && AppInfo.OS != AppInfo.LINUX) {
  4361.                     oPopup.addAlert(oAlertMsg);
  4362.                 }
  4363.                 //FF2 - send via observer
  4364.                 else {
  4365.                     var topic = this.observer.topic;
  4366.                     setTimeout(function() {
  4367.                         var aSubject = new Object();
  4368.                         aSubject.wrappedJSObject = aSubject;
  4369.                         aSubject.message = oAlertMsg;
  4370.                         notifyObservers(aSubject, topic, "");
  4371.                     }, 100);
  4372.                 }
  4373.                 break;
  4374.         }
  4375.     };
  4376.     
  4377.     this._getLinkUrl = function(strPostFix) {
  4378.         //lazy init
  4379.         if (!prefs)
  4380.             prefs = new PrefManager(AlertPrefConsts.prefix, AlertPrefConsts.prefix);
  4381.  
  4382.         var strBaseClientUrl = prefs.GetPref(AlertPrefConsts.clientsServerUrl);
  4383.         if (!strBaseClientUrl) {
  4384.             strBaseClientUrl = AlertConsts.clientsBaseUrl;
  4385.             prefs.SetPref(AlertPrefConsts.clientsServerUrl, strBaseClientUrl);
  4386.         }
  4387.         var arrChannelsIds = AlertFeedsDAL.getChannelsIdsArray();
  4388.         return strBaseClientUrl + "/" + strPostFix + arrChannelsIds[0];
  4389.     };
  4390.  
  4391.     this._setTrayIcon = function(iconUrl, document) {
  4392.         //set to single window
  4393.         if (document) {
  4394.             xulIcon = document.getElementById(iconId);
  4395.             if (xulIcon) xulIcon.src = iconUrl;
  4396.         }
  4397.         //set to all windows
  4398.         else {
  4399.             var arrWindows = getWindows();
  4400.             if (!arrWindows || arrWindows.length == 0) return;
  4401.  
  4402.             var xulIcon = null;
  4403.             for (var i = 0; i < arrWindows.length; i++) {
  4404.                 xulIcon = arrWindows[i].document.getElementById(iconId);
  4405.                 if (xulIcon) xulIcon.src = iconUrl;
  4406.             }
  4407.         }
  4408.     };
  4409.  
  4410.     this._isFeedMessageExists = function(guid) {
  4411.         for (var i = 0; i < arrFeedMessages.length; i++)
  4412.             if (arrFeedMessages[i].guid == guid)
  4413.             return true;
  4414.  
  4415.         return false;
  4416.     };
  4417.  
  4418.     this._notifyNewMessage = function() {
  4419.         var topic = this.observer.topic;
  4420.         setTimeout(function() { notifyObservers(null, topic, ""); }, 300);
  4421.     };
  4422.  
  4423.     this._getMainDialogPosition = function(win) {
  4424.         var statusBarHeight = win.document.getElementById("status-bar").boxObject.height;
  4425.         var x = win.screen.availWidth - alertWidth;
  4426.         var y = win.screen.availHeight - alertHeigth - statusBarHeight;
  4427.  
  4428.         return { "x": x, "y": y };
  4429.     };
  4430.  
  4431.     this._isToShowAlert = function() {
  4432.         if (idleObserver)
  4433.             return !idleObserver.isIdle;
  4434.         else
  4435.             return true;
  4436.     };
  4437.  
  4438.     this._init = function() {
  4439.         if (AppInfo.isGecko19) {
  4440.             idleObserver = new IdleObserver(idleTimeout, this.onIdle, this.onBackFromIdle, this);
  4441.             idleObserver.register();
  4442.         }
  4443.     };
  4444.  
  4445.     this._init();
  4446. };
  4447.  
  4448. var ChatPrefConsts =
  4449. {
  4450.     ChatPrefix: "Chat.",
  4451.     ServerLastCheckTime: "ServerLastCheckTime",
  4452.     ServerLastResponseTime: "ServerLastResponseTime"
  4453. };
  4454.  
  4455. function ChatInfo(oIO, oPref, oProvidersCallback, thatChatManager) {
  4456.  
  4457.     this.filename = "chat" + Dir.sep + "ChatInfo.xml";
  4458.     this.lastUpdateTime = "";
  4459.     this.providersHash;
  4460.     this.publisherRooms;
  4461.     this.publicRooms;
  4462.     this.isLoaded = false;
  4463.     this.mProvidersCallback = oProvidersCallback;
  4464.     this.mIO = oIO;
  4465.     this.mPref = oPref;
  4466.     this.mThatChatManager = thatChatManager;
  4467.  
  4468.     this.loadFromFile = function() {
  4469.         this.isLoaded = false;
  4470.  
  4471.         var strXml = this.mIO.readToolbarFile(this.filename, true);
  4472.         var xmlDoc = XML.GetXmlDocument(strXml);
  4473.         
  4474.         if (xmlDoc)
  4475.             this.loadFromXml(xmlDoc.documentElement);
  4476.     };
  4477.  
  4478.     this.loadFromXml = function(xmlRoot) {
  4479.         this.isLoaded = false;
  4480.         if (!xmlRoot) return;
  4481.  
  4482.         var xmlChild = null;
  4483.         for (var i = 0; i < xmlRoot.childNodes.length; i++) {
  4484.             xmlChild = xmlRoot.childNodes[i];
  4485.             switch (xmlChild.tagName) {
  4486.                 case "LAST_UPDATE_TIME": this.lastUpdateTime = XML.GetXmlNodeValue(xmlChild); break;
  4487.                 case "PROVIDERS": this._parseProviders(xmlChild); break;
  4488.                 case "ROOMS": this._parseRooms(xmlChild); break;
  4489.             }
  4490.         }
  4491.  
  4492.         if ((!this.publisherRooms || this.publisherRooms.Count() == 0)
  4493.             &&
  4494.             (!this.publicRooms || this.publicRooms.Count() == 0)) {
  4495.             this.isLoaded = false;
  4496.             this.lastUpdateTime = "";
  4497.         }
  4498.         else {
  4499.             this.isLoaded = true;
  4500.             if (this.providersHash && this.providersHash.Count() > 0) {
  4501.                 this._registerRoomsToProviders();
  4502.                 this._initProviders();
  4503.             }
  4504.         }
  4505.     };
  4506.  
  4507.     //this function is called after new settings received
  4508.     this.loadFromXmlAndSave = function(xmlRoot) {
  4509.         if (!xmlRoot) return;
  4510.  
  4511.         this.shutdown(true);
  4512.         this.saveToFile(xmlRoot);
  4513.         this.loadFromXml(xmlRoot);
  4514.     };
  4515.  
  4516.     this.saveToFile = function(xmlRoot) {
  4517.         var strXml = XML.GetStringXml(xmlRoot);
  4518.         this.mIO.writeToolbarFile(strXml, this.filename, true);
  4519.     };
  4520.  
  4521.     this.shutdown = function(bReinit) {
  4522.         this._shutdownProviders(bReinit);
  4523.     };
  4524.  
  4525.     this._parseProviders = function(xmlProviders) {
  4526.         this._shutdownProviders();
  4527.         this.providersHash = new HashArray();
  4528.  
  4529.         var xmlProvider = null;
  4530.         for (var i = 0; i < xmlProviders.childNodes.length; i++) {
  4531.             xmlProvider = xmlProviders.childNodes[i];
  4532.             if (xmlProvider.tagName) {
  4533.                 var oProvider = ChatProviderFactory.getProvider(xmlProvider, this.mPref);
  4534.                 if (oProvider)
  4535.                     this.providersHash.Add(oProvider.type, oProvider);
  4536.             }
  4537.         }
  4538.     };
  4539.  
  4540.     this._parseRooms = function(xmlRooms) {
  4541.         this.publisherRooms = new HashArray();
  4542.         this.publicRooms = new HashArray();
  4543.         var xmlRoom = null;
  4544.         for (var i = 0; i < xmlRooms.childNodes.length; i++) {
  4545.             xmlRoom = xmlRooms.childNodes[i];
  4546.             if (xmlRoom.tagName) {
  4547.                 var oRoom = new ChatRoom(xmlRoom);
  4548.                 if (oRoom.isPublisher)
  4549.                     this.publisherRooms.Add(oRoom.id, oRoom);
  4550.                 else
  4551.                     this.publicRooms.Add(oRoom.id, oRoom);
  4552.             }
  4553.         }
  4554.     };
  4555.  
  4556.     this._shutdownProviders = function(bReinit) {
  4557.         if (!this.providersHash) return;
  4558.  
  4559.         var oProvider = null;
  4560.         for (var i = 0; i < this.providersHash.IndexerArray.length; i++) {
  4561.             oProvider = this.providersHash.IndexerArray[i];
  4562.             oProvider.shutdown(bReinit);
  4563.         }
  4564.     };
  4565.  
  4566.     this._registerRoomsToProviders = function() {
  4567.         if (!this.isLoaded) return;
  4568.  
  4569.         this._clearRoomsInProviders();
  4570.         //add rooms to providers
  4571.         var oRoom = null;
  4572.  
  4573.         if (this.publisherRooms)
  4574.             this._registerRoomsToProvidersHelper(this.publisherRooms);
  4575.  
  4576.         if (this.publicRooms)
  4577.             this._registerRoomsToProvidersHelper(this.publicRooms);
  4578.     };
  4579.  
  4580.     this._clearRoomsInProviders = function() {
  4581.         if (!this.providersHash || this.providersHash.Count() == 0) return;
  4582.         
  4583.         for (var i = 0; i < this.providersHash.Count(); i++)
  4584.             this.providersHash.GetByIndex(i).clearRooms();
  4585.     };
  4586.     
  4587.     this._registerRoomsToProvidersHelper = function(hashRooms) {
  4588.         for (var i = 0; i < hashRooms.Count(); i++) {
  4589.             oRoom = hashRooms.GetByIndex(i);
  4590.             if (oRoom.providerRoomInfo)
  4591.                 ChatProviderFactory.registerRoom(oRoom.providerRoomInfo.providerType, oRoom.providerRoomInfo.roomId, this.providersHash);
  4592.         }
  4593.     };
  4594.  
  4595.     this._initProviders = function() {
  4596.         if (!this.providersHash) return;
  4597.  
  4598.         var oProvider = null;
  4599.         for (var i = 0; i < this.providersHash.Count(); i++) {
  4600.             oProvider = this.providersHash.GetByIndex(i);
  4601.             oProvider.init(this.mProvidersCallback, this.mThatChatManager);
  4602.         }
  4603.     };
  4604. }
  4605. function ChatInfoRequest(strCTID, strLastUpdateTime, strUrl, bInvalidateCache, objCallback) {
  4606.     var REQUEST_STRING = "<CHAT_INFO_REQUEST><CTID>CT_ID</CTID><LAST_UPDATE_TIME>LUT</LAST_UPDATE_TIME>INVALIDATE_CACHE</CHAT_INFO_REQUEST>";
  4607.     var POST_PARAM_NAME = "requestXML=";
  4608.     var INITIAL_LAST_UPDATE_TIME = "0001-01-01T00:00:00";
  4609.     var INVALIDATE_CAHCE_TAG = "<IC>TRUE</IC>";
  4610.  
  4611.     //public properties
  4612.     this.callback = objCallback;
  4613.     this.url = strUrl;
  4614.     this.postParams = "";
  4615.  
  4616.     this._init = function() {
  4617.         if (!strLastUpdateTime)
  4618.             strLastUpdateTime = INITIAL_LAST_UPDATE_TIME;
  4619.         
  4620.         var invalidateCacheAlias = (bInvalidateCache) ? INVALIDATE_CAHCE_TAG : "";
  4621.  
  4622.         var reqString = REQUEST_STRING.replace(/CT_ID/, strCTID);
  4623.         reqString = reqString.replace(/LUT/, strLastUpdateTime);
  4624.         reqString = reqString.replace(/INVALIDATE_CACHE/, invalidateCacheAlias);
  4625.         
  4626.         this.postParams = POST_PARAM_NAME + encodeURIComponent(reqString);
  4627.     };
  4628.  
  4629.     this._init();
  4630. };
  4631.  
  4632. ChatInfoRequest.prototype = new BaseServerRequest();
  4633. function ChatProviderRoomInfo(xmlProviderRoomInfo) {
  4634.     this.providerType = '';
  4635.     this.roomId = '';
  4636.  
  4637.     this.init = function(xmlProviderRoomInfo) {
  4638.         var xmlChildNode = null;
  4639.         for (var i = 0; i < xmlProviderRoomInfo.childNodes.length; i++) {
  4640.             xmlChildNode = xmlProviderRoomInfo.childNodes[i];
  4641.             switch (xmlChildNode.tagName) {
  4642.                 case "PROVIDER_TYPE": this.providerType = XML.GetXmlNodeValue(xmlChildNode); break;
  4643.                 case "PROVIDER_ROOM_ID": this.roomId = XML.GetXmlNodeValue(xmlChildNode); break;
  4644.             }
  4645.         }
  4646.     };
  4647.  
  4648.     this.init(xmlProviderRoomInfo);
  4649. }
  4650. //************ Base Chat provider ******************
  4651. function ChatProvider() {
  4652.     this.mPref = null;
  4653.     this.prefPrefix = "";
  4654.     this.defaultInterval = 60;
  4655.     this.roomIdsArr = new Array();
  4656.     
  4657.     this.type = '';
  4658.     this.participantsCountService =
  4659.     {
  4660.         url: '',
  4661.         intervalSec: 0
  4662.     };
  4663.  
  4664.     this.addRoom = function(providerRoomId) {
  4665.         this.roomIdsArr.push(providerRoomId);
  4666.     };
  4667.  
  4668.     this.getLastCheckTime = function() {
  4669.         return this.mPref.GetPref(this.prefPrefix + ChatPrefConsts.ServerLastCheckTime, true);
  4670.     };
  4671.  
  4672.     this.getLastResponseTime = function() {
  4673.         return this.mPref.GetPref(this.prefPrefix + ChatPrefConsts.ServerLastResponseTime, true);
  4674.     };
  4675.     
  4676.     this.init = function(oCallback) {
  4677.         //implement in subclass
  4678.     };
  4679.  
  4680.     this.shutdown = function(bReinit) {
  4681.         //implement in subclass
  4682.     };
  4683.  
  4684.     this.clearRooms = function() {
  4685.         this.roomIdsArr = new Array();
  4686.     };
  4687. }
  4688. var ChatProviderFactory =
  4689. {
  4690.     getProvider: function(xmlProvider, oPref) {
  4691.         var strChatProvider = XML.GetSingleNodeValue(xmlProvider, "PROVIDER_TYPE");
  4692.         if (!strChatProvider) return null;
  4693.         
  4694.         switch (strChatProvider.toUpperCase()) {
  4695.             case "MEEBO": return new ChatProviderMeebo(xmlProvider, oPref);
  4696.             default: return null;
  4697.         }
  4698.     },
  4699.  
  4700.     registerRoom: function(strProviderType, strProviderRoomId, providersHash) {
  4701.         var oProvider = providersHash.GetByID(strProviderType);
  4702.         if (oProvider)
  4703.             oProvider.addRoom(strProviderRoomId);
  4704.     }
  4705. }
  4706. ///<reference path="ChatProvider.js" />
  4707. ///<reference path="..\..\..\CommonFunctions\utilities.js" />
  4708.  
  4709. //************ Meebo Chat provider ******************
  4710. function ChatProviderMeebo(xmlProvider, oPref) {
  4711.     this.mPref = oPref;
  4712.     this.mNewDataCallback = null;
  4713.     this.mThatDataCallback = null;
  4714.     this.mRequestUrl = "";
  4715.     
  4716.     var minInterval = 60; //minimum interval in seconds
  4717.  
  4718.     //pointers to internal thread
  4719.     this.mThread_ServerCheck = null;
  4720.     this.mThread_DefineCheckInterval = null;
  4721.     this.mThread_CheckInetvalRef = null;
  4722.     this.mThread_CheckIsValidData = null;
  4723.  
  4724.     this._init = function(xmlProvider) {
  4725.         var xmlNode = null;
  4726.         for (var i = 0; i < xmlProvider.childNodes.length; i++) {
  4727.             xmlNode = xmlProvider.childNodes[i];
  4728.             if (xmlNode.tagName) {
  4729.                 switch (xmlNode.tagName.toUpperCase()) {
  4730.                     case "PROVIDER_TYPE": this.type = XML.GetXmlNodeValue(xmlNode); break;
  4731.                     case "PARTICIPANTS_COUNT_SERVICE": this._parseParticipantsCountService(xmlNode); break;
  4732.                 }
  4733.             }
  4734.         }
  4735.  
  4736.         this.prefPrefix = ChatPrefConsts.ChatPrefix + this.type + ".";
  4737.     };
  4738.  
  4739.     this._parseParticipantsCountService = function(xmlCountService) {
  4740.         var xmlNode = null;
  4741.         for (var i = 0; i < xmlCountService.childNodes.length; i++) {
  4742.             xmlNode = xmlCountService.childNodes[i];
  4743.             if (xmlNode.tagName) {
  4744.                 switch (xmlNode.tagName.toUpperCase()) {
  4745.                     case "API_URL": this.participantsCountService.url = XML.GetXmlNodeValue(xmlNode); break;
  4746.                     case "API_QUERY_INTERVAL_IN_SECONDS":
  4747.                         var strInterval = XML.GetXmlNodeValue(xmlNode);
  4748.                         this.participantsCountService.intervalSec = (strInterval) ? parseInt(strInterval) : this.defaultInterval;
  4749.                         if (this.participantsCountService.intervalSec < minInterval)
  4750.                             this.participantsCountService.intervalSec = minInterval;
  4751.                         break;
  4752.                 }
  4753.             }
  4754.         }
  4755.     }
  4756.  
  4757.     this.init = function(oCallback, thatCallback) {
  4758.         this.mNewDataCallback = oCallback;
  4759.         this.mThatDataCallback = thatCallback;
  4760.  
  4761.         var iNextCheck = this._getNextCheckInterval();
  4762.         this._createRequestUrl();
  4763.         var self = this;
  4764.         this.mThread_ServerCheck = setTimeout(function() { self._serverRequest(); }, iNextCheck);
  4765.         this.mThread_DefineCheckInterval = setTimeout(function() { self._defineCheckInterval(); }, iNextCheck);
  4766.     };
  4767.  
  4768.     this.shutdown = function(bReinit) {
  4769.         clearTimeout(this.mThread_ServerCheck);
  4770.         clearTimeout(this.mThread_DefineCheckInterval);
  4771.         clearInterval(this.mThread_CheckInetvalRef);
  4772.         clearInterval(this.mThread_CheckIsValidData);
  4773.         this.roomIdsArr = new Array();
  4774.  
  4775.         if (bReinit)
  4776.             this.mPref.SetPref(this.prefPrefix + ChatPrefConsts.ServerLastCheckTime, "", true);
  4777.     };
  4778.  
  4779.     this._createRequestUrl = function() {
  4780.         this.mRequestUrl = this.participantsCountService.url + "&num=" + this.roomIdsArr.length;
  4781.  
  4782.         for (var i = 0; i < this.roomIdsArr.length; i++)
  4783.             this.mRequestUrl += "&" + parseInt(i + 1) + "node=" + this.roomIdsArr[i];
  4784.     };
  4785.  
  4786.     this._getNextCheckInterval = function() {
  4787.         var strLastCheckTime = this.getLastCheckTime();
  4788.         var iLastCheckTime = Date.parse(strLastCheckTime);
  4789.         //never checked, interval 0 - immidiate check
  4790.         if (!iLastCheckTime)
  4791.             return 0;
  4792.  
  4793.         var iNow = Date.parse(Date());
  4794.         //check interval in ms
  4795.         var iCheckIntervalMS = this.participantsCountService.intervalSec * 1000;
  4796.         var iNextCheckIntervalMS = iLastCheckTime + iCheckIntervalMS - iNow;
  4797.  
  4798.         //next check interval is passed, check immidiatly
  4799.         if (iNextCheckIntervalMS <= 0)
  4800.             return 0;
  4801.         else
  4802.             return iNextCheckIntervalMS;
  4803.     };
  4804.  
  4805.     this._defineCheckInterval = function() {
  4806.         var self = this;
  4807.         this.mThread_CheckInetvalRef = setInterval(function() { self._serverRequest(); }, this.participantsCountService.intervalSec * 1000);
  4808.         this.mThread_CheckIsValidData = setInterval(function() { self._checkIsValidData(); }, this.participantsCountService.intervalSec * 1000 * 2);
  4809.     };
  4810.  
  4811.     this._checkIsValidData = function() {
  4812.         var strDateTimeLastResponse = this.mPref.GetPref(this.prefPrefix + ChatPrefConsts.ServerLastResponseTime, true);
  4813.         if (!strDateTimeLastResponse)
  4814.             this.mNewDataCallback.call(this.mThatDataCallback, this.type, null);
  4815.  
  4816.         var iLastResponse = Date.parse(strDateTimeLastResponse);
  4817.         var iNow = Date.parse(Date());
  4818.         if (iNow - iLastResponse > this.participantsCountService.intervalSec * 1000 * 2)
  4819.             this.mNewDataCallback.call(this.mThatDataCallback, this.type, null);
  4820.     };
  4821.  
  4822.     this._serverRequest = function() {
  4823.         var self = this;
  4824.         var objRequest = new Object();
  4825.         objRequest.url = this.mRequestUrl;
  4826.         objRequest.callback = function(strResponse) { self._serverResponse(strResponse) };
  4827.         objRequest.postParams = null;
  4828.  
  4829.         //set last check time to now
  4830.         this.mPref.SetPref(this.prefPrefix + ChatPrefConsts.ServerLastCheckTime, Date(), true);
  4831.         EBServerDataURL.ServiceRequest(objRequest);
  4832.     };
  4833.  
  4834.     this._serverResponse = function(strResponse) {
  4835.         //set last response time to now
  4836.         this.mPref.SetPref(this.prefPrefix + ChatPrefConsts.ServerLastResponseTime, Date(), true);
  4837.  
  4838.         var roomsHash = this._createRoomsInfo(strResponse);
  4839.  
  4840.         if (roomsHash)
  4841.             this.mNewDataCallback.call(this.mThatDataCallback, this.type, roomsHash);
  4842.     };
  4843.  
  4844.     this._createRoomsInfo = function(strJson) {
  4845.         if (!strJson || strJson.length <= 0) return null;
  4846.  
  4847.         var objData = JSON.parse(strJson);
  4848.         if (!objData || objData.stat != "ok") return null;
  4849.  
  4850.         var hashRooms = new HashArray();
  4851.         for (var i = 0; i < objData.data.length; i++)
  4852.             hashRooms.Add(objData.data[i].node, new ProviderRoomData(objData.data[i].node, objData.data[i].participants));
  4853.  
  4854.         return hashRooms;
  4855.     };
  4856.  
  4857.     this._init(xmlProvider);
  4858.     
  4859. };
  4860.  
  4861. ChatProviderMeebo.prototype = new ChatProvider();
  4862. ///<reference path="ChatProviderRoomInfo.js" />
  4863. function ChatRoom(xmlRoom) {
  4864.     this.type = '';
  4865.     this.isPublisher = false;
  4866.     this.id = 0;
  4867.     this.url = '';
  4868.     this.name = '';
  4869.     this.iconUrl = '';
  4870.     this.providerRoomInfo = null;
  4871.  
  4872.     this.init = function(xmlRoom) {
  4873.         var xmlChildNode = null;
  4874.         for (var i = 0; i < xmlRoom.childNodes.length; i++) {
  4875.             xmlChildNode = xmlRoom.childNodes[i];
  4876.             if (xmlChildNode.tagName) {
  4877.                 switch (xmlChildNode.tagName.toUpperCase()) {
  4878.                     case "TYPE":
  4879.                         this.type = XML.GetXmlNodeValue(xmlChildNode);
  4880.                         if (this.type && this.type.toUpperCase() == "PUBLISHER")
  4881.                             this.isPublisher = true;
  4882.                         break;
  4883.                     case "ROOM_ID": this.id = XML.GetXmlNodeValue(xmlChildNode); break;
  4884.                     case "URL": this.url = XML.GetXmlNodeValue(xmlChildNode); break;
  4885.                     case "NAME": this.name = XML.GetXmlNodeValue(xmlChildNode); break;
  4886.                     case "ICON_URL": this.iconUrl = XML.GetXmlNodeValue(xmlChildNode); break;
  4887.                     case "PROVIDER_INFO": this.providerRoomInfo = new ChatProviderRoomInfo(xmlChildNode); break;
  4888.                     default: break;
  4889.                 }
  4890.             }
  4891.         }
  4892.     }
  4893.  
  4894.     this.init(xmlRoom);
  4895. }
  4896. //Conduit chat server data object
  4897. function ConduitChatServerData(strOriginalCTID, strCurrentCTID, strServerUrl, iCheckInterval) {
  4898.     this.originalCTID = strOriginalCTID;
  4899.     this.currentCTID = strCurrentCTID;
  4900.     this.serverUrl = strServerUrl;
  4901.     this.checkInterval = iCheckInterval;
  4902.  
  4903.     this.equalsTo = function(oConduitChatServerData) {
  4904.         if (!(oConduitChatServerData instanceof ConduitChatServerData))
  4905.             return false;
  4906.  
  4907.         if (oConduitChatServerData.originalCTID != this.originalCTID ||
  4908.             oConduitChatServerData.currentCTID != this.currentCTID ||
  4909.             oConduitChatServerData.serverUrl != this.serverUrl ||
  4910.             oConduitChatServerData.checkInterval != this.checkInterval)
  4911.             return false;
  4912.         else
  4913.             return true;
  4914.     };
  4915. };
  4916. //Rooms hash is HashArray(providerRoomsId, numberOfParticipants)
  4917. function ProviderRoomsData(strProviderId, oPref) {
  4918.     this.providerId = strProviderId;
  4919.     this.roomsDataHash;
  4920.     this.arrRooms;
  4921.     this.totalCount = 0;
  4922.     this.prefPrefix = ChatPrefConsts.ChatPrefix + this.providerId + ".rooms.";
  4923.     this.mPref = oPref;
  4924.  
  4925.     this.loadFromPrefs = function(arrRoomsIds, strLastCheckTime, iCheckInterval) {
  4926.         this.arrRooms = arrRoomsIds;
  4927.         this.roomsDataHash = new HashArray();
  4928.         this.totalCount = 0;
  4929.  
  4930.         var strPrefName = "";
  4931.         var iParticipantsCount = 0;
  4932.         var iIntervalFromLastCheckTime = Date.parse(Date()) - Date.parse(strLastCheckTime);
  4933.         var bInvalidateCount = (iIntervalFromLastCheckTime > iCheckInterval + 10) ? true : false;
  4934.  
  4935.         //get rooms participants from prefs
  4936.         if (!bInvalidateCount) {
  4937.             for (var i = 0; i < arrRoomsIds.length; i++) {
  4938.                 strPrefName = this.prefPrefix + arrRoomsIds[i];
  4939.                 iParticipantsCount = this.mPref.GetPref(strPrefName, true);
  4940.                 this.totalCount += iParticipantsCount;
  4941.                 this.roomsDataHash.Add(arrRoomsIds[i], new ProviderRoomData(arrRoomsIds[i], iParticipantsCount));
  4942.             }
  4943.         }
  4944.         //outdated rooms participants data in prefs
  4945.         else
  4946.             this.invalidateCount();
  4947.     };
  4948.  
  4949.     this.load = function(roomsDataHash) {
  4950.         this.roomsDataHash = roomsDataHash;
  4951.         this._calculateTotal();
  4952.     };
  4953.  
  4954.     this.invalidateCount = function() {
  4955.         for (var i = 0; i < this.arrRooms.length; i++)
  4956.             this.roomsDataHash.Add(this.arrRooms[i], new ProviderRoomData(this.arrRooms[i], null));
  4957.         this.totalCount = null;
  4958.     };
  4959.  
  4960.     this.saveToPrefs = function() {
  4961.         if (!this.roomsDataHash) return;
  4962.  
  4963.         var strPrefName = "";
  4964.         var objProviderRoomData = null;
  4965.  
  4966.         for (var i = 0; i < this.roomsDataHash.Count(); i++) {
  4967.             objProviderRoomData = this.roomsDataHash.GetByIndex(i);
  4968.             strPrefName = this.prefPrefix + objProviderRoomData.providerRoomId;
  4969.             this.mPref.SetPref(strPrefName, objProviderRoomData.participants, true);
  4970.         }
  4971.     };
  4972.  
  4973.     this._calculateTotal = function() {
  4974.         this.totalCount = 0;
  4975.         for (var i = 0; i < this.roomsDataHash.Count(); this.totalCount += this.roomsDataHash.GetByIndex(i).participants, i++);
  4976.     };
  4977. };
  4978.  
  4979. //provider room data structure
  4980. function ProviderRoomData(providerRoomId, participants) {
  4981.     this.providerRoomId = providerRoomId;
  4982.     this.participants = participants;
  4983. };
  4984. ///<reference path="..\..\CommonFunctions\XML.js" />
  4985. ///<reference path="..\..\CommonFunctions\Hash.js" />
  4986. ///<reference path="..\..\CommonFunctions\ConsoleLogging.js" />
  4987. ///<reference path="..\..\CommonFunctions\ServerCommunications.js" />
  4988. ///<reference path="..\..\CommonFunctions\utilities.js" />
  4989. ///<reference path="..\..\CommonFunctions\IO\IO.js" />
  4990. ///<reference path="..\..\CommonFunctions\Prefs\Prefs.js" />
  4991. ///<reference path="DataStructures\ChatInfo.js" />
  4992.  
  4993. //main component
  4994. function ConduitChat() {
  4995.  
  4996.     this.mConduitChatServerData = null;
  4997.     this.mChatInfo = null;
  4998.     this.mChatServerManager = null;
  4999.     this.mPref = null;
  5000.     this.mIO = null;
  5001.     this.mProvidersRoomsDataHash = null;
  5002.     this.observersTopic = "EBChat";
  5003.  
  5004.     var reInit = false;
  5005.     var invalidateCache = false;
  5006.  
  5007.     this.init = function(strOriginalCTID, strCurrentCTID, strServerUrl, iCheckInterval) {
  5008.         //chat initialized
  5009.         if (this.mConduitChatServerData) {
  5010.             //by the same data
  5011.             var oConduitChatServerData = new ConduitChatServerData(strOriginalCTID, strCurrentCTID, strServerUrl, iCheckInterval);
  5012.             //another current ctid initilized the toolbar or toolbar refreshed - reInit
  5013.             if (!this.mConduitChatServerData.equalsTo(oConduitChatServerData) || reInit)
  5014.                 this.shutdown(strOriginalCTID, strCurrentCTID, reInit);
  5015.             else
  5016.                 return;
  5017.         }
  5018.         //create IO objects
  5019.         this._initIO(strOriginalCTID, strCurrentCTID);
  5020.  
  5021.         //create this toolbar pair server data (original CTID, current CTID)
  5022.         this.mConduitChatServerData = new ConduitChatServerData(strOriginalCTID, strCurrentCTID, strServerUrl, iCheckInterval);
  5023.  
  5024.         //load chat info from file
  5025.         this.mChatInfo = new ChatInfo(this.mIO, this.mPref, this._onProviderResponse, this);
  5026.         this.mChatInfo.loadFromFile();
  5027.  
  5028.         this._loadProvidersRoomsData();
  5029.  
  5030.         //create and init chat server manager
  5031.         this.mChatServerManager = new ChatServerManager(this.mConduitChatServerData, this.mChatInfo.lastUpdateTime, this.mPref, this._onChatInfoChange, this);
  5032.         
  5033.         this.mChatServerManager.init(reInit || !this.mChatInfo.isLoaded, invalidateCache);
  5034.     };
  5035.  
  5036.     this.shutdown = function(strOriginalCTID, strCurrentCTID, bReinit) {
  5037.         if (this.mChatServerManager) this.mChatServerManager.shutdown();
  5038.         if (this.mChatInfo) this.mChatInfo.shutdown(bReinit);
  5039.     };
  5040.  
  5041.     //this function will be called before init
  5042.     this.onToolbarRefresh = function(bInvalidateCache) {
  5043.         reInit = true;
  5044.         invalidateCache = bInvalidateCache;
  5045.     };
  5046.  
  5047.     this.reInit = function(bInvalidateCache) {
  5048.         this.onToolbarRefresh(bInvalidateCache);
  5049.         this.init(this.mConduitChatServerData.originalCTID,
  5050.                     this.mConduitChatServerData.currentCTID,
  5051.                     this.mConduitChatServerData.serverUrl,
  5052.                     this.mConduitChatServerData.checkInterval);
  5053.     };
  5054.     
  5055.     this.getRoomsInfo = function() {
  5056.         if (!this.mChatInfo || !this.mChatInfo.isLoaded) return null;
  5057.         
  5058.         var publisherRooms = (this.mChatInfo.publisherRooms && this.mChatInfo.publisherRooms.Count() > 0) ?
  5059.                                 this.mChatInfo.publisherRooms : null;
  5060.         var publicRooms = (this.mChatInfo.publicRooms && this.mChatInfo.publicRooms.Count()) ?
  5061.                                 this.mChatInfo.publicRooms : null;
  5062.         
  5063.         return { "publisherRooms": publisherRooms, "publicRooms": publicRooms };
  5064.     };
  5065.  
  5066.     this.getProviderRoomsInfo = function(strProviderId) {
  5067.         if (!this.mProvidersRoomsDataHash) return null;
  5068.         if (!this.mProvidersRoomsDataHash.Contains(strProviderId)) return null;
  5069.  
  5070.         var oProviderRoomsData = this.mProvidersRoomsDataHash.GetByID(strProviderId);
  5071.         return { "rooms": oProviderRoomsData.roomsDataHash, "total": oProviderRoomsData.totalCount};
  5072.     };
  5073.  
  5074.     this.getProvidersRoomsInfo = function() {
  5075.         return this.mProvidersRoomsDataHash;
  5076.     };
  5077.  
  5078.     this.getAllProvidersParticipantsCount = function() {
  5079.         var iCount = 0;
  5080.         if (this.mProvidersRoomsDataHash && this.mProvidersRoomsDataHash.Count() > 0) {
  5081.             for (var i = 0; i < this.mProvidersRoomsDataHash.Count(); i++)
  5082.                 iCount += this.mProvidersRoomsDataHash.GetByIndex(i).totalCount;
  5083.         }
  5084.         else
  5085.             iCount = -1;
  5086.  
  5087.         return iCount;
  5088.     };
  5089.  
  5090.     this._initIO = function(strOriginalCTID, strCurrentCTID) {
  5091.         this.mPref = new PrefManager(strOriginalCTID, strCurrentCTID);
  5092.         this.mIO = new IO(strOriginalCTID, strCurrentCTID);
  5093.     };
  5094.  
  5095.     this._loadProvidersRoomsData = function() {
  5096.         if (!this.mChatInfo.isLoaded || !this.mChatInfo.providersHash) { return; }
  5097.  
  5098.         this.mProvidersRoomsDataHash = new HashArray();
  5099.         var oProviderRoomData = null;
  5100.         var oProvider = null;
  5101.  
  5102.         for (var i = 0; i < this.mChatInfo.providersHash.IndexerArray.length; i++) {
  5103.             oProvider = this.mChatInfo.providersHash.IndexerArray[i];
  5104.             oProviderRoomData = new ProviderRoomsData(oProvider.type, this.mPref);
  5105.             oProviderRoomData.loadFromPrefs(oProvider.roomIdsArr, oProvider.getLastResponseTime(), this.mConduitChatServerData.checkInterval);
  5106.             this.mProvidersRoomsDataHash.Add(oProvider.type, oProviderRoomData);
  5107.         }
  5108.     };
  5109.  
  5110.     //this function is called from chat server manager when new chat info received
  5111.     this._onChatInfoChange = function(xmlChatInfoRoot) {
  5112.         this.mChatInfo.loadFromXmlAndSave(xmlChatInfoRoot);
  5113.         this._loadProvidersRoomsData();
  5114.     };
  5115.  
  5116.     //this function is called from provider server response
  5117.     this._onProviderResponse = function(strProviderId, hashRoomsData) {
  5118.         this._saveProviderResponse(strProviderId, hashRoomsData);
  5119.     };
  5120.  
  5121.     this._saveProviderResponse = function(strProviderId, hashRoomsData) {
  5122.         var oProviderRoomsData = this.mProvidersRoomsDataHash.GetByID(strProviderId);
  5123.         if (hashRoomsData) {
  5124.             oProviderRoomsData.load(hashRoomsData);
  5125.             oProviderRoomsData.saveToPrefs();
  5126.         }
  5127.         else
  5128.             oProviderRoomsData.invalidateCount();
  5129.  
  5130.         //notify observers
  5131.         notifyObservers(null, this.observersTopic, this.mConduitChatServerData.currentCTID);
  5132.     };
  5133. }
  5134. ///<reference path="..\..\CommonFunctions\XML.js" />
  5135. ///<reference path="..\..\CommonFunctions\Hash.js" />
  5136. ///<reference path="..\..\CommonFunctions\ConsoleLogging.js" />
  5137. ///<reference path="..\..\CommonFunctions\ServerCommunications.js" />
  5138. ///<reference path="..\..\CommonFunctions\utilities.js" />
  5139. ///<reference path="..\..\CommonFunctions\IO\IO.js" />
  5140. ///<reference path="..\..\CommonFunctions\Prefs\Prefs.js" />
  5141.  
  5142. //Conduit chat server manager
  5143. function ChatServerManager(objChatServerData, strLastUpdateTime, oPref, oDataChangedCallback, thatChatManager) {
  5144.     
  5145.     this.mChatServerData = objChatServerData;
  5146.     this.mPref = oPref;
  5147.     this.mLastUpdateTime = strLastUpdateTime;
  5148.     this.mDataChangedCallback = oDataChangedCallback;
  5149.     this.mThatChatManager = thatChatManager;
  5150.  
  5151.     var invalidateCache = false;
  5152.     
  5153.     //pointers to internal thread
  5154.     this.mThread_ServerCheck = null;
  5155.     this.mThread_DefineCheckInterval = null;
  5156.     this.mThread_CheckInetvalRef = null;
  5157.  
  5158.     this.init = function(bForceCheck, bInvalidateCache) {
  5159.         invalidateCache = bInvalidateCache;
  5160.         if (bForceCheck) this.mLastUpdateTime = "";
  5161.  
  5162.         var iNextCheck;
  5163.         if (!this.mLastUpdateTime)
  5164.             iNextCheck = 0;
  5165.         else
  5166.             iNextCheck = this._getNextCheckInterval();
  5167.  
  5168.         var self = this;
  5169.         this.mThread_ServerCheck = setTimeout(function() { self._serverRequest(); }, iNextCheck);
  5170.         this.mThread_DefineCheckInterval = setTimeout(function() { self._defineCheckInterval(); }, iNextCheck);
  5171.     };
  5172.  
  5173.     this.shutdown = function() {
  5174.         clearTimeout(this.mThread_ServerCheck);
  5175.         clearTimeout(this.mThread_DefineCheckInterval);
  5176.         clearInterval(this.mThread_CheckInetvalRef);
  5177.     };
  5178.  
  5179.     this._getNextCheckInterval = function() {
  5180.         var strLastCheckTime = this.mPref.GetPref(ChatPrefConsts.ChatPrefix + ChatPrefConsts.ServerLastCheckTime, true);
  5181.         var iLastCheckTime = Date.parse(strLastCheckTime);
  5182.         //never checked, interval 0 - immidiate check
  5183.         if (!iLastCheckTime) {
  5184.             this.mLastUpdateTime = null;
  5185.             return 0;
  5186.         }
  5187.  
  5188.         var iNow = Date.parse(Date());
  5189.         //check interval in ms
  5190.         var iCheckIntervalMS = this.mChatServerData.checkInterval * 60 * 1000;
  5191.         var iNextCheckIntervalMS = iLastCheckTime + iCheckIntervalMS - iNow;
  5192.  
  5193.         //next check interval is passed, check immidiatly
  5194.         if (iNextCheckIntervalMS <= 0)
  5195.             return 0;
  5196.         else
  5197.             return iNextCheckIntervalMS;
  5198.     };
  5199.  
  5200.     this._defineCheckInterval = function() {
  5201.         var self = this;
  5202.         this.mThread_CheckInetvalRef = setInterval(function() { self._serverRequest(); }, this.mChatServerData.checkInterval * 60 * 1000);
  5203.     };
  5204.  
  5205.     this._serverRequest = function() {
  5206.         var self = this;
  5207.         var objRequest = new ChatInfoRequest(this.mChatServerData.currentCTID,
  5208.                                              this.mLastUpdateTime,
  5209.                                              this.mChatServerData.serverUrl,
  5210.                                              invalidateCache,
  5211.                                              function(strResponse) { self._serverResponse(strResponse); });
  5212.  
  5213.         //set last check time to now
  5214.         this.mPref.SetPref(ChatPrefConsts.ChatPrefix + ChatPrefConsts.ServerLastCheckTime, Date(), true);
  5215.         EBServerDataURL.ServiceRequest(objRequest);
  5216.         //use invalidate cache only for one request
  5217.         invalidateCache = false;
  5218.     };
  5219.  
  5220.     this._serverResponse = function(strResponse) {
  5221.         if (!strResponse) return;
  5222.  
  5223.         var xmlResponse = XML.GetXmlDocument(strResponse);
  5224.         var bIsModified = XML.GetSingleNodeValueAsBoolean(xmlResponse, "MODIFIED");
  5225.         if (!bIsModified) return;
  5226.  
  5227.         this.mLastUpdateTime = XML.GetSingleNodeValue(xmlResponse, "LAST_UPDATE_TIME");
  5228.         this.mDataChangedCallback.call(this.mThatChatManager, xmlResponse.documentElement);
  5229.     };
  5230. };
  5231. function Defaults_ImageData(xmlImage) {
  5232.     this.originalPath;
  5233.     this.localPath;
  5234.  
  5235.     this.init = function(xmlImage) {
  5236.         this.originalPath = XML.GetSingleNodeValue(xmlImage, "original_path");
  5237.         this.localPath = XML.GetSingleNodeValue(xmlImage, "local_file_path");
  5238.     };
  5239.  
  5240.     if(xmlImage)
  5241.         this.init(xmlImage);
  5242. };
  5243. function DefaultsManager(chromeName, originalCTID) {
  5244.     this.defaultsFolder = "chrome://" + chromeName + "/skin/defaults/";
  5245.     this.manifestFileName = "manifest.xml";
  5246.     this.settingsFilePath = "";
  5247.     this.imagesHash = null;
  5248.  
  5249.     this.isInit = false;
  5250.     this.isImagesInit = false;
  5251.     this.isSettingsInit = false;
  5252.  
  5253.     this.checkIcon = function(xulElement) {
  5254.         //lazy init
  5255.         if (!this.isInit) this.init();
  5256.         if (!this.isImagesInit) return;
  5257.  
  5258.         var strImageUrl = "";
  5259.         if (xulElement.tagName == "image")
  5260.             strImageUrl = xulElement.getAttribute("src");
  5261.         else
  5262.             strImageUrl = xulElement.getAttribute("image");
  5263.         //if no icon defined, nothing to check
  5264.         if (!strImageUrl) return;
  5265.  
  5266.         //find if icon is in defaults, if not, return
  5267.         var strFullLocalPath = this.checkFileAndGetFullPath(strImageUrl);
  5268.         if (!strFullLocalPath) return;
  5269.  
  5270.         xulElement.setAttribute("image", strFullLocalPath);
  5271.     };
  5272.  
  5273.     this.getImageUrl = function(strImageUrl) {
  5274.         //lazy init
  5275.         if (!this.isInit) this.init();
  5276.         if (!this.isImagesInit) return strImageUrl;
  5277.  
  5278.         var strFullLocalPath = this.checkFileAndGetFullPath(strImageUrl);
  5279.  
  5280.         if (strFullLocalPath)
  5281.             return strFullLocalPath;
  5282.         else
  5283.             return strImageUrl;
  5284.     };
  5285.  
  5286.     this.checkFileAndGetFullPath = function(strIconUrl) {
  5287.         if (!this.imagesHash || this.imagesHash.Count() == 0 || !this.imagesHash.Contains(strIconUrl)) return "";
  5288.  
  5289.         var strLocalPath = this.imagesHash.GetByID(strIconUrl);
  5290.         if (strLocalPath)
  5291.             return this.defaultsFolder + strLocalPath.replace(/\\/g, "/");
  5292.         else
  5293.             return "";
  5294.     };
  5295.  
  5296.     this.getAndCopySettingsFile = function() {
  5297.         //lazy init
  5298.         if (!this.isInit) this.init();
  5299.         if (!this.isSettingsInit) return null;
  5300.         var xmlSettings = XML.GetXmlDocumentFromUrl(this.defaultsFolder + this.settingsFilePath);
  5301.         var oFile = null;
  5302.  
  5303.         oFile = this.copySettingsFile(xmlSettings);
  5304.  
  5305.         return xmlSettings;
  5306.     };
  5307.  
  5308.     //copy the settings file from defaults and delete it in defaults
  5309.     this.copySettingsFile = function(xmlSettings) {
  5310.         try {
  5311.             var strSettings = XML.GetStringXml(xmlSettings);
  5312.             var oIO = new IO(originalCTID, originalCTID);
  5313.             oIO.writeToolbarFile(strSettings, ToolbarManagerConst.settingsFilename, false);
  5314.         }
  5315.         catch (e) {
  5316.             return null;
  5317.         }
  5318.     };
  5319.  
  5320.     this.getManifestXml = function() {
  5321.         var xmlManifest = XML.GetXmlDocumentFromUrl(this.defaultsFolder + this.manifestFileName);
  5322.         return xmlManifest;
  5323.     };
  5324.  
  5325.     this.init = function() {
  5326.         this.isInit = true;
  5327.  
  5328.         var xmlDoc = this.getManifestXml();
  5329.         if (!xmlDoc) return;
  5330.  
  5331.         var xmlSettings = XML.SelectSingleNode(xmlDoc, "settings");
  5332.         var xmlImages = XML.SelectSingleNode(xmlDoc, "images");
  5333.         this.initSettings(xmlSettings);
  5334.         this.initImages(xmlImages);
  5335.     };
  5336.  
  5337.     this.initSettings = function(xmlSettings) {
  5338.         if (!xmlSettings) return;
  5339.  
  5340.         this.settingsFilePath = XML.GetSingleNodeValue(xmlSettings, "local_file_path");
  5341.         this.isSettingsInit = true;
  5342.     };
  5343.  
  5344.     this.initImages = function(xmlImages) {
  5345.         this.imagesHash = new HashArray();
  5346.         if (!xmlImages || xmlImages.childNodes.length == 0) return;
  5347.  
  5348.         var arrImages = xmlImages.getElementsByTagName("image");
  5349.         var oImageData = null;
  5350.  
  5351.         for (var i = 0; i < arrImages.length; i++) {
  5352.             oImageData = new Defaults_ImageData(arrImages[i]);
  5353.             this.imagesHash.Add(oImageData.originalPath, oImageData.localPath);
  5354.         }
  5355.  
  5356.         this.isImagesInit = true;
  5357.     };
  5358. };
  5359. var DefaultsXPCOM =
  5360. {
  5361.     hashManagers: new HashArray(),
  5362.     getManager: function(chromeName, originalCTID) {
  5363.         var manager = null;
  5364.         if (!this.hashManagers.Contains(chromeName)) {
  5365.             manager = new DefaultsManager(chromeName, originalCTID);
  5366.             this.hashManagers.Add(chromeName, manager);
  5367.         }
  5368.         else
  5369.             manager = this.hashManagers.GetByID(chromeName);
  5370.  
  5371.         return manager;
  5372.     }
  5373. };
  5374. /*
  5375. function AccountData() {
  5376. }*/
  5377. /*
  5378. ///<reference path="..\..\CommonFunctions\XML.js" />
  5379. ///<reference path="..\..\CommonFunctions\Hash.js" />
  5380. ///<reference path="..\..\CommonFunctions\ConsoleLogging.js" />
  5381. ///<reference path="..\..\CommonFunctions\ServerCommunications.js" />
  5382. ///<reference path="..\..\CommonFunctions\utilities.js" />
  5383. ///<reference path="..\..\CommonFunctions\IO\IO.js" />
  5384. ///<reference path="..\..\CommonFunctions\Prefs\Prefs.js" />
  5385.  
  5386. function EmailNotifierManager() {
  5387.     var oPref = null;
  5388.     var oIO = null;
  5389.     var isInit = false;
  5390.     var objBrowser = null;
  5391.  
  5392.     this.init = function(strOriginalCTID) {
  5393.         if (isInit) return;
  5394.  
  5395.         isInit = true;
  5396.         objBrowser = new Components.classes["@mozilla.org/embedding/browser/nsWebBrowser;1"]; //.createInstance(Components.interfaces.nsIWebBrowser);
  5397.         //alert(objBrowser.loadURI);
  5398.     };
  5399.  
  5400.     var _init = function(strOriginalCTID) {
  5401.         
  5402.     };
  5403. };
  5404. */function FacebookConsts()
  5405. {
  5406.     this.observer = new Object();
  5407.     this.observer.topic = "EBFacebookTopic";
  5408.     this.observer.loggedIn = "logged in";
  5409.     this.observer.logout = "logout";
  5410.     this.observer.addStar = "add star";
  5411.     this.observer.removeStar = "remove star";
  5412.     this.observer.dynamicMenuReady = "dynamic-menu-ready";
  5413.     
  5414.     this.FB_APP_API_KEY = "f1fd4cc78e14014efe6c7a5de6c12d3a";
  5415.     this.FB_APP_SECRET = "033953958cd0adf2b265bfd247f36f9a";
  5416.     this.FB_API_VER = "1.0";
  5417.  
  5418.     this.FB_URL = "http://www.facebook.com";
  5419.     
  5420.     this.prefix =  "CommunityToolbar.facebook",
  5421.     this.tokenPref = "token";
  5422.     this.sessionKeyPref = "sessionKey";
  5423.     this.sessionSecretPref = "sessionSecret";
  5424.     this.userIdPref = "userId";
  5425.  
  5426.     this.settingsLastCheckTime = "settingsLastCheckTime";
  5427.     this.settingsServiceUrl = "settingsServiceUrl";
  5428.     this.settingsDefaultUrl = "http://facebook.conduit-services.com/Settings.ashx?locale=[LOCALE]&browserType=[BROWSER_TYPE]&toolbarVersion=[TOOLBAR_VERSION]";
  5429.  
  5430.     this.fbAlerts = new Object();
  5431.     this.fbAlerts.prefix = "CommunityToolbar.facebook.alerts";
  5432.     this.fbAlerts.enabled = "enabled";
  5433.     this.fbAlerts.friendReqEnabled = "friendReqEnabled";
  5434.     this.fbAlerts.inboxEnabled = "inboxEnabled";
  5435.     this.fbAlerts.groupsEnabled = "groupsEnabled";
  5436.     this.fbAlerts.eventsEnabled = "eventsEnabled";
  5437.     this.fbAlerts.newsFeedsEnabled = "newsFeedsEnabled";
  5438.  
  5439.     this.settingsDialogPath = "chrome://iobitcom/content/fbSettings.xul";
  5440.     
  5441.     // permissions
  5442.     this.PERM_READ_STREAM = "read_stream";
  5443.     this.PERM_PUBLISH_STREAM = "publish_stream";
  5444.     this.FB_PERM_STATUS_UPDATE = "status_update";
  5445.  
  5446.     this.gadgetType = new Object();
  5447.     this.gadgetType.login ="LOGIN";
  5448.     this.gadgetType.getUpdateStatusPermission = "GET_UPDATE_STATUS_PERMISSION";
  5449.     this.gadgetType.getReadMailboxPermission = "GET_READ_MAILBOX_PERMISSION";
  5450.     this.gadgetType.updateStatusAfterGetPermission = "UPDATE_STATUS_AFTER_PERMISSION";
  5451.     this.gadgetType.updateStatusWithoutAfterGetPermission = "UPDATE_STATUS";
  5452.     this.gadgetType.share = "SHARE";
  5453.  
  5454.     this.gadgetClosingType = new Object();
  5455.     this.gadgetClosingType.close = "Close";
  5456.     this.gadgetClosingType.cancel = "Cancel";
  5457.     this.gadgetClosingType.success = "Success";
  5458.     this.gadgetClosingType.clear = "Clear";
  5459.  
  5460.     this.folder = "facebook";
  5461.     this.dynamicMenuFilename = "menu-{0}.xml";
  5462.     this.settingsFilename = "settings.xml";
  5463. };
  5464.  
  5465.  
  5466. function FacebookAlertsPermissions() {
  5467.     this.facebookAcceptAllCheck = null;
  5468.     this.facebookFriendReqCheck = null;
  5469.     this.facebookInboxCheck = null;
  5470.     this.facebookGroupsCheck = null;
  5471.     this.facebookEventsCheck = null;
  5472.     this.facebookNewFeedCheck = null;
  5473.  
  5474.     this.init = function(checkBoxStatus) {
  5475.         this.facebookAcceptAllCheck = checkBoxStatus.facebookAcceptAllCheck;
  5476.         this.facebookFriendReqCheck = checkBoxStatus.facebookFriendReqCheck;
  5477.         this.facebookInboxCheck = checkBoxStatus.facebookInboxCheck;
  5478.         this.facebookGroupsCheck = checkBoxStatus.facebookGroupsCheck;
  5479.         this.facebookEventsCheck = checkBoxStatus.facebookEventsCheck;
  5480.         this.facebookNewFeedCheck = checkBoxStatus.facebookNewFeedCheck;
  5481.     };
  5482. };
  5483. function FacebookRQ(serviceUrl, arrParams, objCallback, state) {
  5484.     this.callback = objCallback;
  5485.     this.url = serviceUrl;
  5486.     if (arrParams) this.postParams = arrParams.join("&");
  5487.     this.state = state;
  5488. };function FacebookSettingsDS() {
  5489.     this.facebookApiUrl = "";
  5490.     this.notificationsIntervalMM = 0;
  5491.     this.newsFeedsIntervalMM = 0;
  5492.  
  5493.     this.gadget = new Object();
  5494.     this.gadget.facebookSuccessUrl = null;
  5495.     this.gadget.facebookFailureUrl = null;
  5496.     this.gadget.facebookLoginUrl = null;
  5497.     this.gadget.facebookSharerUrl = null;
  5498.     this.gadget.facebookPermissionUrl = null;
  5499.     this.gadget.facebookGetNewsFeedPermission = null;
  5500.     this.gadget.facebookGetInboxPermission = null;
  5501.     this.gadget.facebookSetStatusPermission = null;
  5502.  
  5503.     this.gadget.facebookUpdateStatusUrl = null;
  5504.     this.gadget.facebookUpdateStatusHeight = null;
  5505.     this.gadget.facebookUpdateStatusWidth = null;
  5506.     this.gadget.facebookPermissionHeight = null;
  5507.     this.gadget.facebookPermissionWidth = null;
  5508.     this.gadget.facebookLoginHeight = null;
  5509.     this.gadget.facebookLoginWidth = null;
  5510.     this.gadget.facebookSharerHeight = null;
  5511.     this.gadget.facebookSharerWidth = null;
  5512.     this.gadget.facebookUpdateStatusParam = null;
  5513.  
  5514.     this.links = new Object();
  5515.     this.links.facebookInboxUrl = null;
  5516.     this.links.facebookLogoutUrl = null;
  5517.     this.links.facebookProfileUrl = null;
  5518.     this.links.facebookGroupUrl = null;
  5519.     this.links.facebookEventUrl = null;
  5520.     this.links.facebookNewsFeedMoreUrl = null;
  5521.  
  5522.     this.requests = new Object();
  5523.     this.requests.facebookRequestsUrl = null;
  5524.     this.requests.facebookReqFriend = null;
  5525.     this.requests.facebookReqGroup = null;
  5526.     this.requests.facebookReqEvent = null;
  5527.  
  5528.     this.images = new Object();
  5529.     this.images.facebookInboxImgUrl = null;
  5530.     this.images.facebookFriendReqImgUrl = null;
  5531.     this.images.facebookGroupImgUrl = null;
  5532.     this.images.facebookEventImgUrl = null;
  5533.     this.images.facebookNewsFeedImgUrl = null;
  5534.     this.images.facebookAlertMainImgUrl = null;
  5535.     this.images.facebookDefaultProfileImgUrl = null;
  5536.     this.images.facebookDefaultEvenOrGroupImgUrl = null;
  5537.  
  5538.     this.checkBoxStatus = new Object();
  5539.     this.checkBoxStatus.facebookAcceptAllCheck = null;
  5540.     this.checkBoxStatus.facebookFriendReqCheck = null;
  5541.     this.checkBoxStatus.facebookInboxCheck = null;
  5542.     this.checkBoxStatus.facebookGroupsCheck = null;
  5543.     this.checkBoxStatus.facebookEventsCheck = null;
  5544.     this.checkBoxStatus.facebookNewFeedCheck = null;
  5545.  
  5546.     this.init = function(xmlFBSettings, facebookItem) {
  5547.         var xmlNode = null;
  5548.         var innerNode = null;
  5549.         for (var i = 0; i < xmlFBSettings.childNodes.length; i++) {
  5550.             xmlNode = xmlFBSettings.childNodes[i];
  5551.             switch (xmlFBSettings.childNodes[i].tagName) {
  5552.                 case "API":
  5553.                     this.facebookApiUrl = XML.GetSingleNodeValue(xmlNode, "URL");
  5554.                     break;
  5555.                 case "NOTIFICATIONS":
  5556.                     this.notificationsIntervalMM = XML.GetSingleNodeValueAsInteger(xmlNode, "INTERVAL_MM", 4);
  5557.                     break;
  5558.                 case "NEWS_FEED":
  5559.                     this.newsFeedsIntervalMM = XML.GetSingleNodeValueAsInteger(xmlNode, "INTERVAL_MM", 4);
  5560.                     break;
  5561.                 case "GADGETS":
  5562.                     this.gadget.facebookSuccessUrl = XML.GetSingleNodeValue(xmlNode, "SUCCESS_URL");
  5563.                     this.gadget.facebookFailureUrl = XML.GetSingleNodeValue(xmlNode, "FAILURE_URL");
  5564.                     for (var j = 0; j < xmlNode.childNodes.length; j++) {
  5565.                         if (xmlNode.childNodes[j].tagName == 'LOGIN') {
  5566.                             innerNode = xmlNode.childNodes[j];
  5567.                             break;
  5568.                         }
  5569.                     }
  5570.                     this.gadget.facebookLoginUrl = XML.GetSingleNodeValue(innerNode, "URL");
  5571.                     this.gadget.facebookLoginHeight = XML.GetSingleNodeValueAsInteger(innerNode, "HEIGHT");
  5572.                     this.gadget.facebookLoginWidth = XML.GetSingleNodeValueAsInteger(innerNode, "WIDTH");
  5573.                     for (var j = 0; j < xmlNode.childNodes.length; j++) {
  5574.                         if (xmlNode.childNodes[j].tagName == 'UPDATE_STATUS') {
  5575.                             innerNode = xmlNode.childNodes[j];
  5576.                             break;
  5577.                         }
  5578.                     }
  5579.                     this.gadget.facebookUpdateStatusUrl = XML.GetSingleNodeValue(innerNode, "URL");
  5580.                     this.gadget.facebookUpdateStatusParams = XML.GetSingleNodeValue(innerNode, "PARAMS");
  5581.                     this.gadget.facebookUpdateStatusHeight = XML.GetSingleNodeValueAsInteger(innerNode, "HEIGHT");
  5582.                     this.gadget.facebookUpdateStatusWidth = XML.GetSingleNodeValueAsInteger(innerNode, "WIDTH");
  5583.  
  5584.                     for (var j = 0; j < xmlNode.childNodes.length; j++) {
  5585.                         if (xmlNode.childNodes[j].tagName == 'SHARER') {
  5586.                             innerNode = xmlNode.childNodes[j];
  5587.                             break;
  5588.                         }
  5589.                     }
  5590.  
  5591.                     this.gadget.facebookSharerUrl = XML.GetSingleNodeValue(innerNode, "URL");
  5592.                     this.gadget.facebookSharerHeight = XML.GetSingleNodeValueAsInteger(innerNode, "HEIGHT");
  5593.                     this.gadget.facebookSharerWidth = XML.GetSingleNodeValueAsInteger(innerNode, "WIDTH");
  5594.  
  5595.                     for (var j = 0; j < xmlNode.childNodes.length; j++) {
  5596.                         if (xmlNode.childNodes[j].tagName == 'PERMISSION') {
  5597.                             innerNode = xmlNode.childNodes[j];
  5598.                             break;
  5599.                         }
  5600.                     }
  5601.  
  5602.                     this.gadget.facebookPermissionUrl = XML.GetSingleNodeValue(innerNode, "URL");
  5603.                     this.gadget.facebookPermissionHeight = XML.GetSingleNodeValueAsInteger(innerNode, "HEIGHT");
  5604.                     this.gadget.facebookPermissionWidth = XML.GetSingleNodeValueAsInteger(innerNode, "WIDTH");
  5605.  
  5606.                     for (var j = 0; j < innerNode.childNodes.length; j++) {
  5607.                         if (innerNode.childNodes[j].tagName == 'TYPES') {
  5608.                             innerNode = innerNode.childNodes[j];
  5609.                             break;
  5610.                         }
  5611.                     }
  5612.                     this.gadget.facebookGetNewsFeedPermission = XML.GetSingleNodeValue(innerNode, "NEWS_FEED");
  5613.                     this.gadget.facebookGetInboxPermission = XML.GetSingleNodeValue(innerNode, "INBOX");
  5614.                     this.gadget.facebookSetStatusPermission = XML.GetSingleNodeValue(innerNode, "STATUS");
  5615.                     break;
  5616.                 case "LINKS":
  5617.                     this.links.facebookInboxUrl = XML.GetSingleNodeValue(xmlNode, "INBOX_URL");
  5618.                     this.links.facebookLogoutUrl = XML.GetSingleNodeValue(xmlNode, "LOGOUT_URL");
  5619.                     this.links.facebookProfileUrl = XML.GetSingleNodeValue(xmlNode, "PROFILE_URL");
  5620.                     this.links.facebookGroupUrl = XML.GetSingleNodeValue(xmlNode, "GROUP_URL");
  5621.                     this.links.facebookEventUrl = XML.GetSingleNodeValue(xmlNode, "EVENT_URL");
  5622.                     this.links.facebookNewsFeedMoreUrl = XML.GetSingleNodeValue(xmlNode, "NEWS_FEED_MORE_LINK");
  5623.                     break;
  5624.                 case "REQUESTS":
  5625.                     this.requests.facebookRequestsUrl = XML.GetSingleNodeValue(xmlNode, "URL");
  5626.  
  5627.                     for (var j = 0; j < xmlNode.childNodes.length; j++) {
  5628.                         if (xmlNode.childNodes[j].tagName == 'TYPES') {
  5629.                             innerNode = xmlNode.childNodes[j];
  5630.                             break;
  5631.                         }
  5632.                     }
  5633.                     this.requests.facebookReqFriend = XML.GetSingleNodeValue(innerNode, "FRIEND");
  5634.                     this.requests.facebookReqGroup = XML.GetSingleNodeValue(innerNode, "GROUP");
  5635.                     this.requests.facebookReqEvent = XML.GetSingleNodeValue(innerNode, "EVENT");
  5636.                     break;
  5637.                 case "IMAGES":
  5638.                     this.images.facebookInboxImgUrl = XML.GetSingleNodeValue(xmlNode, "INBOX");
  5639.                     this.images.facebookFriendReqImgUrl = XML.GetSingleNodeValue(xmlNode, "FRIEND_REQ");
  5640.                     this.images.facebookGroupImgUrl = XML.GetSingleNodeValue(xmlNode, "GROUP");
  5641.                     this.images.facebookEventImgUrl = XML.GetSingleNodeValue(xmlNode, "EVENT");
  5642.                     this.images.facebookNewsFeedImgUrl = XML.GetSingleNodeValue(xmlNode, "NEWS_FEED");
  5643.                     this.images.facebookAlertMainImgUrl = XML.GetSingleNodeValue(xmlNode, "ALERT_MAIN");
  5644.                     this.images.facebookDefaultProfileImgUrl = XML.GetSingleNodeValue(xmlNode, "DEFAULT_PROFILE");
  5645.                     this.images.facebookDefaultEvenOrGroupImgUrl = XML.GetSingleNodeValue(xmlNode, "DEFAULT_GROUP_EVENT");
  5646.                     break;
  5647.                 case "ALERTS_DEFAULTS":
  5648.                     this.checkBoxStatus.facebookAcceptAllCheck = (facebookItem.facebookAcceptAllCheck == null) ?
  5649.                         XML.GetSingleNodeValueAsBoolean(xmlNode, "ACCEPT_ALL") :
  5650.                         facebookItem.facebookAcceptAllCheck;
  5651.  
  5652.                     this.checkBoxStatus.facebookFriendReqCheck = (facebookItem.facebookFriendReqCheck == null) ?
  5653.                         XML.GetSingleNodeValueAsBoolean(xmlNode, "FRIEND_REQUESTS") :
  5654.                         facebookItem.facebookFriendReqCheck;
  5655.  
  5656.                     this.checkBoxStatus.facebookInboxCheck = (facebookItem.facebookInboxCheck == null) ?
  5657.                         XML.GetSingleNodeValueAsBoolean(xmlNode, "INBOX") :
  5658.                         facebookItem.facebookInboxCheck;
  5659.  
  5660.                     this.checkBoxStatus.facebookGroupsCheck = (facebookItem.facebookGroupsCheck == null) ?
  5661.                         XML.GetSingleNodeValueAsBoolean(xmlNode, "GROUPS") :
  5662.                         facebookItem.facebookGroupsCheck;
  5663.  
  5664.                     this.checkBoxStatus.facebookEventsCheck = (facebookItem.facebookEventsCheck == null) ?
  5665.                         XML.GetSingleNodeValueAsBoolean(xmlNode, "EVENTS") :
  5666.                         facebookItem.facebookEventsCheck;
  5667.  
  5668.                     this.checkBoxStatus.facebookNewFeedCheck = (facebookItem.facebookNewFeedCheck == null) ?
  5669.                         XML.GetSingleNodeValueAsBoolean(xmlNode, "NEWS_FEED") :
  5670.                         facebookItem.facebookNewFeedCheck;
  5671.                     break;
  5672.                 default:
  5673.                     break;
  5674.             }
  5675.         }
  5676.     };
  5677. };
  5678. function FacebookSettingsRQ(strUrl, locale, version, objCallback) {
  5679.     this.url = "";
  5680.     this.callback = objCallback;
  5681.     this.state = null;
  5682.     this.postParams = null;
  5683.  
  5684.     this.init = function() {
  5685.         this.url = strUrl.replace(/\[LOCALE\]/, locale).replace(/\[BROWSER_TYPE\]/, "FF").replace(/\[TOOLBAR_VERSION\]/, version);
  5686.     };
  5687.     this.init();
  5688. };var FacebookXPCOM =
  5689. {
  5690.     consts: new FacebookConsts(),
  5691.     facebookManager: null,
  5692.     init: function() {
  5693.     var that = this;
  5694.         this.__defineGetter__("manager", function() {
  5695.             if (!that.facebookManager) {
  5696.                 that.facebookManager = new FacebookManager();
  5697.             }
  5698.             return that.facebookManager;
  5699.         });
  5700.     }
  5701. };
  5702.  
  5703. FacebookXPCOM.init();
  5704. function FacebookAlertsManager(objPrefsFromSettings, lp, toolbarName) {
  5705.     var fbConsts = FacebookXPCOM.consts.fbAlerts; 
  5706.     var oPrefs = new PrefManager(fbConsts.prefix);
  5707.     var _lpManager = lp;
  5708.     var _toolbarName = toolbarName;
  5709.     var settingsWindowName = "fbSettingsWindowName";
  5710.     var aboutWindowName = "fbAboutWindowName";
  5711.     var alertManager = AlertXPCOM.manager;
  5712.     var fbAlertJS = "";
  5713.     var userId = null;
  5714.     var fbAlertHtmlTemplate = '{4}<div> <div style="font-family:Verdana; font-size: 10px; color: #7c99c5; margin-bottom:2px;">{0}</div> <table class="msgText"> <tr> <td valign="top" style="padding-right:5px;"><a {5} ><img src="{1}" alt="" border="0" style=\"max-width:50px; max-height:50px;\" onload="if(this.width > 50) this.width = 50;" /></a></td> <td valign="top" style="padding-right:5px;"><img src="{2}" alt="" border="0"/></td> <td valign="top" style="padding-top:0px;">{3}</td> </tr> </table> </div><script>if(typeof OnLoad!= "undefined") OnLoad();</script>';
  5715.     var headerCssStyle = { "color": "#004498", "fontFamily": "Arial", "isBold": true };
  5716.  
  5717.     this.__defineGetter__("enabled", function() { return oPrefs.GetPref(fbConsts.enabled, false, objPrefsFromSettings.checkBoxStatus.facebookAcceptAllCheck); });
  5718.     this.__defineGetter__("friendReqEnabled", function() { return oPrefs.GetPref(fbConsts.friendReqEnabled, false, objPrefsFromSettings.checkBoxStatus.facebookFriendReqCheck); });
  5719.     this.__defineGetter__("inboxEnabled", function() { return oPrefs.GetPref(fbConsts.inboxEnabled, false, objPrefsFromSettings.checkBoxStatus.facebookInboxCheck); });
  5720.     this.__defineGetter__("groupsEnabled", function() { return oPrefs.GetPref(fbConsts.groupsEnabled, false, objPrefsFromSettings.checkBoxStatus.facebookGroupsCheck ); });
  5721.     this.__defineGetter__("eventsEnabled", function() { return oPrefs.GetPref(fbConsts.eventsEnabled, false, objPrefsFromSettings.checkBoxStatus.facebookEventsCheck); });
  5722.     this.__defineGetter__("newsFeedsEnabled", function() {return oPrefs.GetPref(fbConsts.newsFeedsEnabled, false, objPrefsFromSettings.checkBoxStatus.facebookNewFeedCheck); });
  5723.  
  5724.     this.__defineSetter__("userId", function(val) { userId = val; });
  5725.     this.__defineSetter__("enabled", function(val) { oPrefs.SetPref(fbConsts.enabled, val); });
  5726.     this.__defineSetter__("friendReqEnabled", function(val) { oPrefs.SetPref(fbConsts.friendReqEnabled, val); });
  5727.     this.__defineSetter__("inboxEnabled", function(val) { oPrefs.SetPref(fbConsts.inboxEnabled, val); });
  5728.     this.__defineSetter__("groupsEnabled", function(val) { oPrefs.SetPref(fbConsts.groupsEnabled, val); });
  5729.     this.__defineSetter__("eventsEnabled", function(val) { oPrefs.SetPref(fbConsts.eventsEnabled, val); });
  5730.     this.__defineSetter__("newsFeedsEnabled", function(val) { oPrefs.SetPref(fbConsts.newsFeedsEnabled, val); });
  5731.  
  5732.     this.updateLanguagePackAndToolbarName = function(lp, toolbarName) {
  5733.         _lpManager = lp;
  5734.         _toolbarName = toolbarName;
  5735.     };
  5736.     
  5737.     this.openSettingsDialog = function(win) {
  5738.         if (!win) win = getWindow();
  5739.         var strParams = "chrome,dependent,modal,resizeable=no,titlebar=yes,centerscreen";
  5740.         win.openDialog(FacebookXPCOM.consts.settingsDialogPath, settingsWindowName, strParams);
  5741.     };
  5742.  
  5743.     var getFBAlertJSContent = function() {
  5744.         var oFile;
  5745.         oFile = __LOCATION__.clone().parent.parent;
  5746.         oFile.append("defaults");
  5747.         oFile.append("fbAlert.js");
  5748.  
  5749.         fbAlertJS = File.read(oFile);
  5750.     };
  5751.     
  5752.     var getInnerALink = function(strUrl) {
  5753.         var strInnerALink = stringFormat(" href='{0}' class='ebLink msgText' ", strUrl);
  5754.         return strInnerALink;
  5755.     };
  5756.  
  5757.     var getAlertHeader = function() {
  5758.         return _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_HEADER").replace(/\[TOOLBAR_NAME\]/, _toolbarName);
  5759.     };
  5760.  
  5761.     var fillUsersHash = function(arrUsers) {
  5762.         var userHash = new HashArray();
  5763.         for (var i = 0; i < arrUsers.length; i++)
  5764.             userHash.Add(arrUsers[i].uid, arrUsers[i]);
  5765.  
  5766.         return userHash;
  5767.     };
  5768.  
  5769.     /*
  5770.     var strJson = '(';
  5771.     strJson += ' [{"name":"Yuval Shahar","uid":885595556,"pic_square":"http:\/\/profile.ak.fbcdn.net\/object2\/1468\/44\/n191017999840_4686.jpg"},';
  5772.     strJson += '{"name":"Omri Conduit","uid":100000224352922,"pic_square":"http:\/\/profile.ak.fbcdn.net\/v223\/641\/2\/q100000224352922_1895.jpg"},';
  5773.     strJson += '{"name":"Yuval Shahar","uid":100000207559049,"pic_square":""}]';
  5774.     strJson += '])';
  5775.     */
  5776.  
  5777.     var buildEventsOrGroupsAlerts = function(arrData, lpTitle, lpInner, url, urlAlias, innerAlias, iconUrl, idProperty) {
  5778.         var html = "";
  5779.         var headerText = _lpManager.GetByIDNL(lpTitle);
  5780.         var titleImage = objPrefsFromSettings.images.facebookAlertMainImgUrl;
  5781.         var innerText = "";
  5782.         var linkToEvent = "";
  5783.         var data = null;
  5784.         for (var i = 0; i < arrData.length; i++) {
  5785.             data = arrData[i];
  5786.             linkToEvent = url.replace(urlAlias, data[idProperty]);
  5787.             innerText = _lpManager.GetByIDNL(lpInner);
  5788.             innerText = innerText.replace(/EB_FB_LINK1/, getInnerALink(linkToEvent));
  5789.             innerText = innerText.replace(innerAlias, data.name);
  5790.             html = stringFormat(fbAlertHtmlTemplate,
  5791.                                     getAlertHeader(),
  5792.                                     (data.pic_big) ? data.pic_big : objPrefsFromSettings.images.facebookDefaultEvenOrGroupImgUrl,
  5793.                                     iconUrl,
  5794.                                     innerText,
  5795.                                     "",
  5796.                                     "");
  5797.  
  5798.             var guid = (idProperty == "gid") ? "FB_" + userId + "_GROUP_" + data[idProperty] :
  5799.                                                 "FB_" + userId + "_EVENT_" + data[idProperty];
  5800.  
  5801.             var alertItem = new AlertItem(headerText, headerCssStyle, titleImage, html, false, guid, true, null, objPrefsFromSettings.notificationsIntervalMM * 60);
  5802.             alertManager.sendInternalAlert(alertItem);
  5803.         }
  5804.     };
  5805.  
  5806.     var buildUsersAlerts = function(users) {
  5807.         var html = "";
  5808.         var headerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_FRIENDS_TITLE");
  5809.         var titleImage = objPrefsFromSettings.images.facebookAlertMainImgUrl;
  5810.         var innerText = "";
  5811.         var linkToUserProfile = "";
  5812.         for (var i = 0; i < users.length; i++) {
  5813.             linkToUserProfile = objPrefsFromSettings.links.facebookProfileUrl.replace(/EB_FB_USER_ID/, users[i].uid);
  5814.             innerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_FRIENDS_HTML");
  5815.             innerText = innerText.replace(/EB_FB_LINK1/, getInnerALink(linkToUserProfile));
  5816.             innerText = innerText.replace(/EB_FB_USER_NAME/, users[i].name);
  5817.             innerText = innerText.replace(/EB_FB_LINK2/, getInnerALink(objPrefsFromSettings.requests.facebookRequestsUrl.replace(/EB_FB_REQ_TYPE/, objPrefsFromSettings.requests.facebookReqFriend)));
  5818.             html = stringFormat(fbAlertHtmlTemplate,
  5819.                                     getAlertHeader(),
  5820.                                     (users[i].pic_big) ? users[i].pic_big : objPrefsFromSettings.images.facebookDefaultProfileImgUrl,
  5821.                                     objPrefsFromSettings.images.facebookFriendReqImgUrl,
  5822.                                     innerText,
  5823.                                     "",
  5824.                                     getInnerALink(linkToUserProfile));
  5825.  
  5826.             var guid = "FB_" + userId + "_FRIEND_" + users[i].uid;
  5827.             var alertItem = new AlertItem(headerText, headerCssStyle, titleImage, html, false, guid, true, null, objPrefsFromSettings.notificationsIntervalMM * 60);
  5828.             alertManager.sendInternalAlert(alertItem);
  5829.         }
  5830.     };
  5831.  
  5832.     this.buildAlertsForMessages = function(json) {
  5833.         var html = "";
  5834.         var headerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_TITLE");
  5835.         var titleImage = objPrefsFromSettings.images.facebookAlertMainImgUrl;
  5836.         var innerText = "";
  5837.         var linkToUserProfile = "";
  5838.         for (var i = 0; i < json.length; i++) {
  5839.             linkToUserProfile = objPrefsFromSettings.links.facebookProfileUrl.replace(/EB_FB_USER_ID/, json[i].uid);
  5840.             innerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_HTML");
  5841.             innerText = innerText.replace(/EB_FB_LINK1/, getInnerALink(linkToUserProfile));
  5842.             innerText = innerText.replace(/EB_FB_USER_NAME/, json[i].name);
  5843.             innerText = innerText.replace(/EB_FB_LINK2/, getInnerALink(objPrefsFromSettings.links.facebookInboxUrl));
  5844.             html = stringFormat(fbAlertHtmlTemplate,
  5845.                                     getAlertHeader(),
  5846.                                     (json[i].pic_square) ? json[i].pic_square : objPrefsFromSettings.images.facebookDefaultProfileImgUrl,
  5847.                                     objPrefsFromSettings.images.facebookInboxImgUrl,
  5848.                                     innerText,
  5849.                                     "",
  5850.                                     getInnerALink(linkToUserProfile));
  5851.  
  5852.             var guid = "FB_" + userId + "_INBOX_" + json[i].uid;
  5853.             var alertItem = new AlertItem(headerText, headerCssStyle, titleImage, html, false, guid, true, null, objPrefsFromSettings.notificationsIntervalMM * 60);
  5854.             alertManager.sendInternalAlert(alertItem);
  5855.         }
  5856.     };
  5857.  
  5858.     this.buildAlertsForUnreadMail = function(unreadNum) {
  5859.         var innerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_GENERAL_HTML");
  5860.         var titleImage = objPrefsFromSettings.images.facebookAlertMainImgUrl;
  5861.         var headerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_TITLE");
  5862.         innerText = innerText.replace(/EB_FB_LINK1/, getInnerALink(objPrefsFromSettings.links.facebookInboxUrl));
  5863.         html = stringFormat(fbAlertHtmlTemplate,
  5864.                                     getAlertHeader(),
  5865.                                     "",
  5866.                                     objPrefsFromSettings.images.facebookInboxImgUrl,
  5867.                                     innerText,
  5868.                                     "",
  5869.                                     "");
  5870.         var guid = "FB_" + userId + "_INBOX_NO_PERMISSION";
  5871.         var alertItem = new AlertItem(headerText, headerCssStyle, titleImage, html, false, guid, true, null, objPrefsFromSettings.notificationsIntervalMM * 60);
  5872.         alertManager.sendInternalAlert(alertItem);
  5873.     };
  5874.     
  5875.     /*
  5876.     var json3 = '(';
  5877.     json3 += '[{"name": "events", "fql_result_set": [{ "name": "lan party", "pic_big": "", "eid":"21323"},{ "name": "lan party22", "pic_big": "http:\/\/profile.ak.fbcdn.net\/object2\/1468\/44\/n191017999840_4686.jpg", "eid":"213223"}]},';
  5878.     json3 += '{"name": "groups", "fql_result_set": [{ "name": "free me", "pic_big": "", "gid":"21323"},{ "name": "lan party123", "pic_big": "", "gid":"2133323"}]},';
  5879.     json3 += '{"name": "users", "fql_result_set": [{ "name": "sami", "pic_big": ""},{ "name": "lan party1123", "pic_big": ""}]}] ';
  5880.     json3 += ')';
  5881.     */
  5882.  
  5883.     this.buildAlertsForNotifications = function(json) {
  5884.         for (var i = 0; i < json.length; i++) {
  5885.             switch (json[i].name) {
  5886.                 case "events":
  5887.                     buildEventsOrGroupsAlerts(json[i].fql_result_set,
  5888.                         "CTLP_STR_ID_FACEBOOK_ALERT_EVENTS_TITLE",
  5889.                         "CTLP_STR_ID_FACEBOOK_ALERT_EVENTS_HTML",
  5890.                         objPrefsFromSettings.links.facebookEventUrl,
  5891.                         "EB_FB_EVENT_ID",
  5892.                         "EB_FB_EVENT_NAME",
  5893.                         objPrefsFromSettings.images.facebookEventImgUrl,
  5894.                         "eid");
  5895.                     break;
  5896.                 case "groups":
  5897.                     buildEventsOrGroupsAlerts(json[i].fql_result_set,
  5898.                     "CTLP_STR_ID_FACEBOOK_ALERT_GROUPS_TITLE",
  5899.                     "CTLP_STR_ID_FACEBOOK_ALERT_GROUPS_HTML",
  5900.                     objPrefsFromSettings.links.facebookGroupUrl,
  5901.                     "EB_FB_GROUP_ID",
  5902.                     "EB_FB_GROUP_NAME",
  5903.                     objPrefsFromSettings.images.facebookGroupImgUrl,
  5904.                     "gid");
  5905.                     break;
  5906.                 case "users":
  5907.                     buildUsersAlerts(json[i].fql_result_set);
  5908.                     break;
  5909.                 default: break;
  5910.             }
  5911.         }
  5912.     };
  5913.     
  5914.     /*
  5915.     var strJson2 = '(';
  5916.     strJson2 += '{"feeds":';
  5917.     strJson2+= '[{"time":1254228879,"uid":885595556,"message":"bla bla http://www.zap.co.il/ sdfsdfsdf sdfsdfsdf sdfsdfasdf asdfasdf asdfasdfasd fasdfasdfasdf asdfasdfasdf asdfasdfasdf asdfasdfasdf sadfasdf asd fas asdf asd fasdf asdf"},';
  5918.     strJson2+= '{"time":1253986091,"uid":885595556,"message":"bla bla 2 324234 vfsadf 3908098 qwerf 234`23rwerqwe wer3241234 qwerwer32 werqwer sdf"},';
  5919.     strJson2+= '{"time":1253777984,"uid":885595556,"message":"bla bla 3"},';
  5920.     strJson2+= '{"time":1253645741,"uid":885595556,"message":"bla bla 4"},';
  5921.     strJson2+= '{"time":1253617715,"uid":100000224352922,"message":"bla bla 5"}] ,';
  5922.     strJson2+= '"users":';
  5923.     strJson2+= '[{"name":"Yuval Shahar","uid":885595556,"pic_square":"http:\/\/profile.ak.fbcdn.net\/v227\/1975\/110\/q885595556_3433.jpg"},';
  5924.     strJson2+= '{"name":"Omri Conduit","uid":100000224352922,"pic_square":"http:\/\/profile.ak.fbcdn.net\/v223\/641\/2\/q100000224352922_1895.jpg"}]}';
  5925.     strJson2 += ')';*/
  5926.  
  5927.     this.buildAlertsForNewFeeds = function(json) {
  5928.         if (!json.users || !json.feeds) return;
  5929.  
  5930.         if (!fbAlertJS)
  5931.             getFBAlertJSContent();
  5932.         var userHash = fillUsersHash(json.users);
  5933.         var feed = null;
  5934.         var html = "";
  5935.         var headerText = _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_NEWS_FEED_TITLE");
  5936.         var titleImage = objPrefsFromSettings.images.facebookAlertMainImgUrl;
  5937.  
  5938.         var innerText = "";
  5939.         var linkToUserProfile = "";
  5940.         var user = null;
  5941.         var localfbAlertJS = "";
  5942.         for (var i = 0; i < json.feeds.length; i++) {
  5943.             feed = json.feeds[i];
  5944.             user = userHash.GetByID(feed.uid);
  5945.             linkToUserProfile = objPrefsFromSettings.links.facebookNewsFeedMoreUrl.replace(/EB_FB_USER_ID/, feed.uid).replace(/EB_FB_NEWS_FEED_ID/, feed.status_id);
  5946.             //replace aliases in JS
  5947.             localfbAlertJS = stringFormat(fbAlertJS,
  5948.                                         _lpManager.GetByIDNL("CTLP_STR_ID_FACEBOOK_ALERT_MORE"),
  5949.                                         linkToUserProfile, 45, 187, 3);
  5950.  
  5951.             innerText = "<a EB_FB_LINK1>EB_FB_USER_NAME</a> EB_FB_STATUS_MESSAGE";
  5952.             innerText = innerText.replace(/EB_FB_LINK1/, getInnerALink(linkToUserProfile));
  5953.             innerText = innerText.replace(/EB_FB_USER_NAME/, user.name);
  5954.             var msg = "<span>" + feed.message.replace(/\s/g, "</span> <span>") + "</span>";
  5955.             innerText = innerText.replace(/EB_FB_STATUS_MESSAGE/, msg);
  5956.             innerText = "<div id=\"mainDiv\" style=\"overflow:visible;\">" + innerText + "</div>";
  5957.             html = stringFormat(fbAlertHtmlTemplate,
  5958.                                     getAlertHeader(),
  5959.                                     (user.pic_square) ? user.pic_square : objPrefsFromSettings.images.facebookDefaultProfileImgUrl,
  5960.                                     objPrefsFromSettings.images.facebookNewsFeedImgUrl,
  5961.                                     innerText,
  5962.                                     localfbAlertJS,
  5963.                                     getInnerALink(linkToUserProfile));
  5964.  
  5965.             var guid = "FB_" + userId + "_NEWS_FEED_" + user.uid + "_" + feed.time;
  5966.             var alertItem = new AlertItem(headerText, headerCssStyle, titleImage, html, false, guid, true, objPrefsFromSettings.newsFeedsIntervalMM * 60);
  5967.             alertManager.sendInternalAlert(alertItem);
  5968.         }
  5969.     };
  5970. };
  5971. function FacebookManager() {
  5972.     var serviceManager = null;
  5973.     var hashSettingsManagers = new HashArray();
  5974.     var hashDynamicMenusXml = new HashArray2();
  5975.     var _alertsPermissions = null;
  5976.     this.facebookSettings = null;
  5977.     
  5978.     this.alertsManager = null;
  5979.     var idleObserver = null;
  5980.     var idleTimeoutSec = 60;
  5981.  
  5982.     this.isInit = false;
  5983.     this.isLoggedIn = false;
  5984.     this.isCheckInFirstTime = false;
  5985.     this.inboxUnreadNum = -1;
  5986.     this.friendsRequestNum = -1;
  5987.     this.groupsRequestNum = -1;
  5988.     this.eventsRequestNum = -1;
  5989.     this.userName = null;
  5990.  
  5991.     var isInboxNeedStar = false;
  5992.     var isEventNeedStar = false;
  5993.     var isFriendReqNeedStar = false;
  5994.     var isGroupNeedStar = false;
  5995.     var _lp = null;
  5996.     var _toolbarName = null;
  5997.     
  5998.     this.__defineGetter__("isStarred", function() {
  5999.         return isInboxNeedStar || isEventNeedStar || isFriendReqNeedStar || isGroupNeedStar;
  6000.     });
  6001.  
  6002.     this.__defineSetter__("isStarred", function(val) {
  6003.         isInboxNeedStar = isEventNeedStar = isFriendReqNeedStar = isGroupNeedStar = val;
  6004.         if (!val)
  6005.             notifyObservers(null, FacebookXPCOM.consts.observer.topic, FacebookXPCOM.consts.observer.removeStar);
  6006.     });
  6007.     
  6008.     var readMailPermission = false;
  6009.     var EventInvitesList = null;  
  6010.     var FriendRequestsList = null;
  6011.     var GroupInvitesList = null;
  6012.     
  6013.     var nextLastKnownUnreadMsgUpdateTime  = -1;
  6014.     var updateStatusPermissionCallBack;
  6015.     var getUserDataCallBack;
  6016.     var prefs = new PrefManager(FacebookXPCOM.consts.prefix, FacebookXPCOM.consts.prefix);
  6017.     var oIO = new IO(CommonData.ConduitFolder, CommonData.ConduitFolder);
  6018.  
  6019.     this.init = function() {
  6020.         var self = this;
  6021.         this.isInit = true;
  6022.         this.facebookSettings = this.loadSettings();
  6023.         if (!this.facebookSettings) {
  6024.             var settingsManager = hashSettingsManagers.GetByIndex(0);
  6025.             settingsManager.request(true);
  6026.             this.isInit = false;
  6027.             return;
  6028.         }
  6029.  
  6030.         this.alertsManager = new FacebookAlertsManager(this.facebookSettings, _lp, _toolbarName);
  6031.         serviceManager = new FacebookServiceManager(function(res, method) { self.handleResponse(res, method); },
  6032.                                                     this.alertsManager, this.facebookSettings);
  6033.         this.loadPrefs();
  6034.         this.registerIdleObserver();
  6035.         this.checkPreConditions();
  6036.         this.getUser();
  6037.     };
  6038.  
  6039.     this.register = function(facebookItem, lp, toolbarName, locale) {
  6040.         var self = this;
  6041.         //init settings manager
  6042.         if (!hashSettingsManagers.Contains(locale)) {
  6043.             var settingsManager = new FacebookSettingsManager(prefs,
  6044.                                         facebookItem.serviceIntervalSec,
  6045.                                         facebookItem.serviceUrl,
  6046.                                         locale,
  6047.                                         function(xmlRoot, locale) { self.onSettingsResponse(xmlRoot, locale); });
  6048.             settingsManager.request(false);
  6049.             hashSettingsManagers.Add(locale, settingsManager);
  6050.         }
  6051.  
  6052.         if (!_alertsPermissions) {
  6053.             _alertsPermissions = new FacebookAlertsPermissions();
  6054.             _alertsPermissions.init(facebookItem);
  6055.             _lp = lp;
  6056.             _toolbarName = toolbarName;
  6057.         }
  6058.  
  6059.         if (!hashDynamicMenusXml.Contains(locale)) {
  6060.             var xmlDynamicMenu = this.loadDynamicMenuXml(locale);
  6061.             if (xmlDynamicMenu)
  6062.                 hashDynamicMenusXml.Add(locale, xmlDynamicMenu);
  6063.             //if no menu exists locally, force get it
  6064.             else {
  6065.                 var settingsManager = hashSettingsManagers.GetByID(locale);
  6066.                 if (settingsManager)
  6067.                     settingsManager.request(true);
  6068.                 this.isInit = false;
  6069.                 return;
  6070.             }
  6071.         }
  6072.  
  6073.         if (!this.isInit) this.init();
  6074.     };
  6075.  
  6076.     this.updateLanguagePackAndToolbarName = function(lp, toolbarName) {
  6077.         this.alertsManager.updateLanguagePackAndToolbarName(lp, toolbarName);
  6078.     };
  6079.  
  6080.     this.checkStatus = function() {
  6081.         if (this.isLoggedIn)
  6082.             notifyObservers(null, FacebookXPCOM.consts.observer.topic, FacebookXPCOM.consts.observer.loggedIn);
  6083.         else
  6084.             notifyObservers(null, FacebookXPCOM.consts.observer.topic, FacebookXPCOM.consts.observer.logout);
  6085.     };
  6086.     
  6087.     this.checkPreConditions = function() {
  6088.         if (serviceManager.sessionKey && serviceManager.sessionSecret && serviceManager.userId)
  6089.             return true;
  6090.         return false;
  6091.     };
  6092.  
  6093.     this.logout = function() {
  6094.         serviceManager.RequestForLogout();
  6095.         this.cleanData();
  6096.     };
  6097.  
  6098.     this.cleanData = function() {
  6099.         serviceManager.shutdown();
  6100.         //TODO: maybe shutdown settings services
  6101.         EventInvitesList = null;
  6102.         FriendRequestsList = null;
  6103.         GroupInvitesList = null;
  6104.         nextLastKnownUnreadMsgUpdateTime = -1;
  6105.     };
  6106.     
  6107.     this.clearSessionData = function() {
  6108.         serviceManager.sessionKey = serviceManager.sessionSecret = serviceManager.userId=0;
  6109.         this.isLoggedIn = false;
  6110.     };
  6111.     
  6112.     this.createToken = function() {
  6113.         serviceManager.Request('facebook.auth.createToken');
  6114.     };
  6115.  
  6116.     this.getUser = function() {
  6117.         this.isCheckInFirstTime = true;
  6118.         serviceManager.Request('facebook.users.getLoggedInUser');
  6119.     };
  6120.  
  6121.     this.getUserNameForFirstTime = function() {
  6122.         serviceManager.getUserNameForFirstTime();
  6123.     };
  6124.  
  6125.     this.setStatus = function(status) {
  6126.         serviceManager.Request('facebook.status.set', status);
  6127.     };
  6128.     
  6129.     this.checkUpdateStatusPermission = function(callback) {
  6130.         updateStatusPermissionCallBack = callback;
  6131.         serviceManager.Request('facebook.users.hasAppPermission', this.facebookSettings.gadget.facebookSetStatusPermission, 'facebook.users.hasAppPermission.status');
  6132.     };
  6133.  
  6134.     this.checkReadMailPermission = function() {
  6135.         serviceManager.Request('facebook.users.hasAppPermission', this.facebookSettings.gadget.facebookGetInboxPermission, 'facebook.users.hasAppPermission.readMail');
  6136.     };
  6137.  
  6138.     this.getUserDataForUpdateStatus = function(callback) {
  6139.         getUserDataCallBack = callback;
  6140.         serviceManager.getUserDataForUpdateStatus();
  6141.     };
  6142.     
  6143.     this.clearPrefs = function() {
  6144.         if (prefs.HasUserValue(FacebookXPCOM.consts.sessionKeyPref))
  6145.             prefs.Clear(FacebookXPCOM.consts.sessionKeyPref);
  6146.         if (prefs.HasUserValue(FacebookXPCOM.consts.sessionSecretPref))
  6147.             prefs.Clear(FacebookXPCOM.consts.sessionSecretPref);
  6148.         if (prefs.HasUserValue(FacebookXPCOM.consts.userIdPref))
  6149.             prefs.Clear(FacebookXPCOM.consts.userIdPref);
  6150.     };
  6151.     
  6152.     this.loadPrefs = function() {
  6153.         if (prefs.HasUserValue(FacebookXPCOM.consts.sessionKeyPref))
  6154.             serviceManager.sessionKey = prefs.GetPref(FacebookXPCOM.consts.sessionKeyPref);
  6155.         if (prefs.HasUserValue(FacebookXPCOM.consts.sessionSecretPref))
  6156.             serviceManager.sessionSecret = prefs.GetPref(FacebookXPCOM.consts.sessionSecretPref);
  6157.         if (prefs.HasUserValue(FacebookXPCOM.consts.userIdPref))
  6158.             serviceManager.userId = prefs.GetPref(FacebookXPCOM.consts.userIdPref);        
  6159.     };
  6160.  
  6161.     this.updateData = function(jasonObj) {
  6162.         serviceManager.sessionKey = jasonObj.session_key;
  6163.         prefs.SetPref(FacebookXPCOM.consts.sessionKeyPref, jasonObj.session_key);
  6164.         serviceManager.sessionSecret = jasonObj.secret;
  6165.         prefs.SetPref(FacebookXPCOM.consts.sessionSecretPref, jasonObj.secret);
  6166.         var userIdStr = jasonObj.uid.toString();
  6167.         serviceManager.userId = userIdStr;
  6168.         prefs.SetPref(FacebookXPCOM.consts.userIdPref, userIdStr);
  6169.     };
  6170.  
  6171.     this.updateNotifications = function(strJson) {
  6172.         var notificationsJsonObj = JSON.parse(strJson);
  6173.         if (!this.isResponseOk(notificationsJsonObj)) return;
  6174.         if (!notificationsJsonObj) return;
  6175.         this.inboxUnreadNum = notificationsJsonObj.messages.unread;
  6176.         this.eventsRequestNum = this.getNumFromList(notificationsJsonObj.event_invites);
  6177.         this.friendsRequestNum = this.getNumFromList(notificationsJsonObj.friend_requests);
  6178.         this.groupsRequestNum = this.getNumFromList(notificationsJsonObj.group_invites);
  6179.  
  6180.         var newInboxTime = notificationsJsonObj.messages.most_recent;
  6181.         if (newInboxTime > nextLastKnownUnreadMsgUpdateTime && nextLastKnownUnreadMsgUpdateTime > -1)
  6182.             isInboxNeedStar = true;
  6183.         else
  6184.             isInboxNeedStar = false;
  6185.         nextLastKnownUnreadMsgUpdateTime = notificationsJsonObj.messages.most_recent;
  6186.  
  6187.         if (!EventInvitesList)
  6188.             EventInvitesList = new Array();
  6189.         else {
  6190.             serviceManager.getEventInvitesDeltaList = this.getDeltaList(notificationsJsonObj.event_invites, EventInvitesList);
  6191.             if (serviceManager.getEventInvitesDeltaList && serviceManager.getEventInvitesDeltaList.length > 0)
  6192.                 isEventNeedStar = true;
  6193.             else
  6194.                 isEventNeedStar = false;
  6195.         }
  6196.         EventInvitesList = notificationsJsonObj.event_invites;
  6197.  
  6198.         if (!FriendRequestsList)
  6199.             FriendRequestsList = new Array();
  6200.         else {
  6201.             serviceManager.getFriendRequestsDeltaList = this.getDeltaList(notificationsJsonObj.friend_requests, FriendRequestsList);
  6202.             if (serviceManager.getFriendRequestsDeltaList && serviceManager.getFriendRequestsDeltaList.length > 0)
  6203.                 isFriendReqNeedStar = true;
  6204.             else
  6205.                 isFriendReqNeedStar = false;
  6206.         }
  6207.         FriendRequestsList = notificationsJsonObj.friend_requests;
  6208.  
  6209.         if (!GroupInvitesList)
  6210.             GroupInvitesList = new Array();
  6211.         else {
  6212.             serviceManager.getGroupInvitesDeltaList = this.getDeltaList(notificationsJsonObj.group_invites, GroupInvitesList);
  6213.             if (serviceManager.getGroupInvitesDeltaList && serviceManager.getGroupInvitesDeltaList.length > 0)
  6214.                 isGroupNeedStar = true;
  6215.             else
  6216.                 isGroupNeedStar = false;
  6217.         }
  6218.         GroupInvitesList = notificationsJsonObj.group_invites;
  6219.  
  6220.         if (this.isStarred)
  6221.             notifyObservers(null, FacebookXPCOM.consts.observer.topic, FacebookXPCOM.consts.observer.addStar);
  6222.     };
  6223.  
  6224.     this.getDeltaList = function(newList, oldList) {
  6225.  
  6226.         if (!newList.length) {
  6227.             oldList = null;
  6228.             return null;
  6229.         }
  6230.         if (!oldList) {
  6231.             oldList = newList;
  6232.             return newList;
  6233.         }
  6234.         var tmpArray = new Array();
  6235.         for (var i = 0; i < newList.length; i++) {
  6236.             if (!this.isItemInList(newList[i],oldList)) tmpArray.push(newList[i]);
  6237.         }
  6238.         return tmpArray;
  6239.     };
  6240.  
  6241.     this.isItemInList = function(item, list) {
  6242.         for (var i = 0; i < list.length; i++) {
  6243.             if (list[i] == item) return true;
  6244.         }
  6245.         return false;
  6246.     };
  6247.     
  6248.     this.getDateToAlerts = function() {
  6249.         serviceManager.RequestDataForAlerts();
  6250.     };
  6251.  
  6252.     this.getNumFromList = function(StrList) {
  6253.         if (!StrList.length) return 0;
  6254.         return StrList.length;
  6255.     };
  6256.  
  6257.     this.handleResponse = function(text, method) {
  6258.         switch (method) {
  6259.             case ('facebook.users.getLoggedInUser'):
  6260.                 if (text == serviceManager.userId && this.checkPreConditions()) {
  6261.                     this.isLoggedIn = true;
  6262.                     serviceManager.initAlertRequests();
  6263.                     this.getUserNameForFirstTime();
  6264.                     this.alertsManager.userId = text;
  6265.                 }
  6266.                 else
  6267.                     this.isLoggedIn = false;
  6268.                 this.checkStatus();
  6269.                 break;
  6270.             case ('facebook.auth.createToken'):
  6271.                 text = text.substr(1, text.length - 2);
  6272.                 serviceManager.token = text;
  6273.                 prefs.SetPref(FacebookXPCOM.consts.tokenPref, text);
  6274.                 this.getUser();
  6275.                 break;
  6276.  
  6277.             case ('facebook.fql.getUserNameForFirstTime'):
  6278.                 var nameObj = JSON.parse(text);
  6279.                 if (!this.isResponseOk(nameObj)) return;
  6280.                 this.userName = nameObj[0].name;
  6281.                 break;
  6282.  
  6283.             case ('facebook.notifications.get'):
  6284.                 this.updateNotifications(text);
  6285.                 this.getDateToAlerts();
  6286.                 serviceManager.lastKnownUnreadMsgUpdateTime = nextLastKnownUnreadMsgUpdateTime;
  6287.                 break;
  6288.             case ('facebook.alerts.data'):
  6289.                 if (text) {
  6290.                     var alertsJsonObj = JSON.parse(text);
  6291.                     this.alertsManager.buildAlertsForNotifications(alertsJsonObj);
  6292.                 }
  6293.                 break;
  6294.             case ('facebook.logout'):
  6295.                 this.clearSessionData();
  6296.                 this.clearPrefs();
  6297.                 this.checkStatus();
  6298.                 serviceManager.lastCheckTimeForNotifications = -1;
  6299.                 serviceManager.lastCheckTimeForNewFeeds = -1;
  6300.                 break;
  6301.  
  6302.             case ('facebook.users.hasAppPermission.readMail'):
  6303.                 if (text == 1)
  6304.                     readMailPermission = true;
  6305.                 else
  6306.                     readMailPermission = false;
  6307.                 this.getNotifications();
  6308.                 break;
  6309.  
  6310.             case ('facebook.users.hasAppPermission.status'):
  6311.                 if (updateStatusPermissionCallBack) {
  6312.                     updateStatusPermissionCallBack(text);
  6313.                     updateStatusPermissionCallBack = null;
  6314.                 }
  6315.                 break;
  6316.             case ('facebook.fql.newMessages'):
  6317.                 var alertsJsonObj = JSON.parse(text);
  6318.                 if (!this.isResponseOk(alertsJsonObj)) return;
  6319.                 if (alertsJsonObj.error_code == '612') {
  6320.                     if (isInboxNeedStar)
  6321.                         this.alertsManager.buildAlertsForUnreadMail(this.inboxUnreadNum);
  6322.                 }
  6323.                 else
  6324.                     this.alertsManager.buildAlertsForMessages(alertsJsonObj);
  6325.                 break;
  6326.             case ('facebook.fql.usersForNewFeeds'):
  6327.                 if (text) {
  6328.                     var alertsJsonObj = JSON.parse(text);
  6329.                     if (!this.isResponseOk(alertsJsonObj)) return;
  6330.                     this.alertsManager.buildAlertsForNewFeeds(alertsJsonObj);
  6331.                 }
  6332.                 break;
  6333.             case ('facebook.fql.getUserDataForUpdateStatus'):
  6334.                 if (getUserDataCallBack) {
  6335.                     if (readMailPermission)
  6336.                         getUserDataCallBack(text, FacebookXPCOM.consts.gadgetType.updateStatusWithoutAfterGetPermission);
  6337.                     else
  6338.                         getUserDataCallBack(text, FacebookXPCOM.consts.gadgetType.updateStatusAfterGetPermission);
  6339.                     getUserDataCallBack = null;
  6340.                 }
  6341.                 break;
  6342.  
  6343.         }
  6344.     };
  6345.  
  6346.     this.isResponseOk = function(jsonObj) {
  6347.         return (!jsonObj.error_code || jsonObj.error_code == '612');
  6348.     };
  6349.  
  6350.     this.__defineGetter__("sessionKey", function() { return serviceManager.sessionKey; });
  6351.  
  6352.     this.onIdle = function() {
  6353.         serviceManager.isIdle = true;
  6354.     };
  6355.  
  6356.     this.onBackFromIdle = function() {
  6357.         serviceManager.isIdle = false;
  6358.         if (serviceManager.forceNotifications) {
  6359.             serviceManager._defineNotificationsInterval();
  6360.             serviceManager.forceNotifications = false;
  6361.         }
  6362.         if (serviceManager.forceNewFeeds) {
  6363.             serviceManager._defineNewFeedsInterval();
  6364.             serviceManager.forceNewFeeds = false;
  6365.         }
  6366.     };
  6367.  
  6368.     this.registerIdleObserver = function() {
  6369.         if (AppInfo.isGecko19) {
  6370.             idleObserver = new IdleObserver(idleTimeoutSec, this.onIdle, this.onBackFromIdle, this);
  6371.             idleObserver.register();
  6372.         }
  6373.     };
  6374.  
  6375.     this.unregisterIdleObserver = function() {
  6376.         if (!idleObserver) return;
  6377.         idleObserver.unregister();
  6378.     };
  6379.  
  6380.     //settings functions
  6381.     this.getDynamicMenuItem = function(locale, facebookItem) {
  6382.         if (!hashDynamicMenusXml.Contains(locale)) return null;
  6383.  
  6384.         var xmlDynamicMenu = hashDynamicMenusXml.GetByID(locale);
  6385.         var objData = facebookItem.objData;
  6386.         var oData = new ToolbarItemData(xmlDynamicMenu,
  6387.                                         ToolbarDataParsingXPCOM.ComponentType.Settings,
  6388.                                         objData.isPublisher,
  6389.                                         objData.chromeName,
  6390.                                         objData.originalCTID,
  6391.                                         objData.actingCTID);
  6392.         var dynamicMenuItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(oData);
  6393.         dynamicMenuItem.DisableUsage = true;
  6394.         return dynamicMenuItem;
  6395.     };
  6396.  
  6397.     var getDynamicMenuFilepath = function(locale) {
  6398.         return stringFormat("{0}{1}{2}", FacebookXPCOM.consts.folder, Dir.sep, stringFormat(FacebookXPCOM.consts.dynamicMenuFilename, locale));
  6399.     };
  6400.     
  6401.     var getSettingsFilepath = function () {
  6402.         return stringFormat("{0}{1}{2}", FacebookXPCOM.consts.folder, Dir.sep, FacebookXPCOM.consts.settingsFilename);
  6403.     };
  6404.  
  6405.     this.updateDynamicMenu = function(xmlDynamicMenu, locale) {
  6406.         if (!xmlDynamicMenu) return;
  6407.         //save dynamic menu into file (by locale)
  6408.         oIO.writeToolbarFile(XML.GetStringXml(xmlDynamicMenu), getDynamicMenuFilepath(locale));
  6409.         //replace/add this menu to hash, in order not to load it each time per toolbar.
  6410.         hashDynamicMenusXml.Add(locale, xmlDynamicMenu);
  6411.  
  6412.         if (!this.isInit) this.init();
  6413.         //broadcast dynamic menu changed
  6414.         var aSubject = new Object(); aSubject.wrappedJSObject = aSubject;
  6415.         aSubject.locale = locale;
  6416.         notifyObservers(aSubject, FacebookXPCOM.consts.observer.topic, FacebookXPCOM.consts.observer.dynamicMenuReady);
  6417.     };
  6418.  
  6419.     this.updateSettings = function(xmlSettings) {
  6420.         //save new settings
  6421.         oIO.writeToolbarFile(XML.GetStringXml(xmlSettings), getSettingsFilepath());
  6422.         //update in memory settings object
  6423.         this.facebookSettings = new FacebookSettingsDS();
  6424.         this.facebookSettings.init(xmlSettings, _alertsPermissions);
  6425.  
  6426.         if (!this.isInit) this.init();
  6427.     };
  6428.  
  6429.     this.loadSettings = function() {
  6430.         var strSettings = oIO.readToolbarFile(getSettingsFilepath());
  6431.         if (!strSettings) return null;
  6432.  
  6433.         var xmlSettings = XML.GetXmlDocument(strSettings);
  6434.         if (!XML.IsLegal(xmlSettings)) return null;
  6435.  
  6436.         var objFacebookSettings = new FacebookSettingsDS();
  6437.         objFacebookSettings.init(xmlSettings.documentElement, _alertsPermissions);
  6438.         return objFacebookSettings;
  6439.     };
  6440.  
  6441.     this.loadDynamicMenuXml = function(locale) {
  6442.         var strDynamicMenu = oIO.readToolbarFile(getDynamicMenuFilepath(locale));
  6443.         if (!strDynamicMenu) return null;
  6444.  
  6445.         var xmlDynamicMenu = XML.GetXmlDocument(strDynamicMenu);
  6446.         if (!XML.IsLegal(xmlDynamicMenu)) return null;
  6447.  
  6448.         return xmlDynamicMenu.documentElement;
  6449.     };
  6450.     
  6451.     this.onSettingsResponse = function(xmlRoot, locale) {
  6452.         //save and update dynamic menu
  6453.         var xmlDynamicMenu = XML.SelectSingleNode(xmlRoot, "DYNAMIC_MENU");
  6454.         this.updateDynamicMenu(xmlDynamicMenu, locale);
  6455.  
  6456.         //save and update settings
  6457.         xmlRoot.removeChild(xmlDynamicMenu);
  6458.         this.updateSettings(xmlRoot);
  6459.     };
  6460. };
  6461. function FacebookServiceManager(objCallback, facebookAlertsManager, facebookPrefFromSetting) {
  6462.     this.isIdle = false;
  6463.     this.token;         // authenticated login/security token for facebook
  6464.     this.sessionKey;     // session key to be used in order to retrieve information
  6465.     this.sessionSecret; // session secret, to be used instead of app-secret
  6466.     this.userId;
  6467.  
  6468.     this.lastKnownUnreadMsgUpdateTime = -1;
  6469.     this.lastKnownUnreadFeedUpdateTime = -1;
  6470.     this.getEventInvitesDeltaList;
  6471.     this.getFriendRequestsDeltaList;
  6472.     this.getGroupInvitesDeltaList;
  6473.           
  6474.     
  6475.     this.lastCheckTimeForNotifications = -1;
  6476.     this.lastCheckTimeForNewFeeds= -1;
  6477.     this.notificationsIntervalMM = facebookPrefFromSetting.notificationsIntervalMM;
  6478.     this.newsFeedsIntervalMM = facebookPrefFromSetting.newsFeedsIntervalMM;
  6479.  
  6480.     var tmpDataForNewFeeds;
  6481.     var mThread_NewFeedsInetvalRef;
  6482.     var mThread_NotificationsInetvalRef;
  6483.     this.forceNotifications = false; 
  6484.     this.forceNewFeeds = false;
  6485.     var that = this;
  6486.  
  6487.     this.Request = function(method, text, callbackState) {
  6488.         if (!callbackState) callbackState = method;
  6489.         var self = this;
  6490.         var arrParams = this.createFacebookRequestPostParams(method, text);
  6491.         var oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams, 
  6492.                                         function(strResponse, o, method) { self.onResponse(strResponse, o, method); }, callbackState);
  6493.         EBServerDataURL.ServiceRequest(oRequest);
  6494.     };
  6495.  
  6496.     this.initAlertRequests = function() {
  6497.         that._defineNewFeedsInterval();
  6498.         that._defineNotificationsInterval();
  6499.     };
  6500.  
  6501.     this.shutdown = function() {
  6502.         if (mThread_NewFeedsInetvalRef) clearTimeout(mThread_NewFeedsInetvalRef);
  6503.         if (mThread_NotificationsInetvalRef) clearTimeout(mThread_NotificationsInetvalRef);
  6504.         mThread_NotificationsInetvalRef = null;
  6505.         mThread_NewFeedsInetvalRef = null;
  6506.         this.lastKnownUnreadMsgUpdateTime = -1;
  6507.         this.lastKnownUnreadFeedUpdateTime = -1;
  6508.         this.lastCheckTimeForNotifications = -1;
  6509.         this.getEventInvitesDeltaList = null;
  6510.         this.getFriendRequestsDeltaList = null;
  6511.         this.getGroupInvitesDeltaList = null;
  6512.     };
  6513.  
  6514.     this._defineNewFeedsInterval = function() {
  6515.         this.requestNewFeeds();
  6516.         mThread_NewFeedsInetvalRef = setInterval(function() { that.requestNewFeeds(); }, that.newsFeedsIntervalMM * 60 * 1000);
  6517.     };
  6518.  
  6519.     this._defineNotificationsInterval = function() {
  6520.         this.requestNotifications();
  6521.         mThread_NotificationsInetvalRef = setInterval(function() { that.requestNotifications(); }, that.notificationsIntervalMM * 60 * 1000);
  6522.     };
  6523.  
  6524.     this.requestNewFeeds = function() {
  6525.         if (!this.isIdle) {
  6526.             if (facebookAlertsManager.enabled && facebookAlertsManager.newsFeedsEnabled) {
  6527.                 var self = this;
  6528.                 this.forceNewFeeds = false;
  6529.                 var queryStr = (this.lastKnownUnreadFeedUpdateTime < 0) ?
  6530.                 "SELECT time FROM status WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=" + this.userId + ") LIMIT 1" :
  6531.                 "SELECT uid,time,message,status_id FROM status WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=" + this.userId + ") AND time>" + this.lastKnownUnreadFeedUpdateTime;
  6532.                 var arrParams = this.createFacebookRequestPostParams('facebook.fql.query', queryStr);
  6533.                 var oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams, function(strResponse, o, method) { self.onResponse(strResponse, o, method); }, 'facebook.fql.newFeeds');
  6534.                 EBServerDataURL.ServiceRequest(oRequest);
  6535.             }
  6536.         }
  6537.         else {
  6538.             this.forceNewFeeds = true;
  6539.             clearTimeout(mThread_NewFeedsInetvalRef);
  6540.         }
  6541.     };
  6542.  
  6543.  
  6544.     this.requestNotifications = function() {
  6545.         if (!this.isIdle) {
  6546.             this.forceNotifications = false;
  6547.             var self = this;
  6548.             var arrParams = this.createFacebookRequestPostParams('facebook.notifications.get');
  6549.             var oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams, function(strResponse, o, method) { self.onResponse(strResponse, o, method); }, 'facebook.notifications.get');
  6550.             EBServerDataURL.ServiceRequest(oRequest);
  6551.         }
  6552.         else {
  6553.             this.forceNotifications = true;
  6554.             clearTimeout(mThread_NotificationsInetvalRef);
  6555.         }
  6556.     };
  6557.  
  6558.     this.getUserDataForUpdateStatus = function() {
  6559.         var querysStr
  6560.         var arrParams;
  6561.         var oRequest;
  6562.         var self = this;
  6563.  
  6564.         querysStr = "SELECT name, pic_square, status ,profile_update_time FROM user WHERE uid=" + this.userId;
  6565.  
  6566.         arrParams = this.createFacebookRequestPostParams('facebook.fql.query', querysStr);
  6567.         oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams, function(strResponse, o, method) { self.onResponse(strResponse, o, method); }, 'facebook.fql.getUserDataForUpdateStatus');
  6568.         EBServerDataURL.ServiceRequest(oRequest);
  6569.     };
  6570.  
  6571.     this.getUserNameForFirstTime = function() {
  6572.         var querysStr = "SELECT name FROM user WHERE uid=" + this.userId;
  6573.         var arrParams = this.createFacebookRequestPostParams('facebook.fql.query', querysStr);
  6574.         var self = this;
  6575.         var oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams, function(strResponse, o, method) { self.onResponse(strResponse, o, method); }, 'facebook.fql.getUserNameForFirstTime');
  6576.         EBServerDataURL.ServiceRequest(oRequest);
  6577.     };
  6578.  
  6579.     this.RequestDataForAlerts = function() {
  6580.         if (!facebookAlertsManager.enabled || this.isIdle) return;
  6581.  
  6582.         var queriesStr = new Array();
  6583.         var arrParams;
  6584.         var oRequest;
  6585.         if (this.getGroupInvitesDeltaList && this.getGroupInvitesDeltaList.length > 0 && facebookAlertsManager.groupsEnabled)
  6586.             queriesStr.push("\"groups\":\"SELECT gid,name,pic_big FROM group WHERE gid IN(" + this.getGroupInvitesDeltaList.join(',') + ")\"");
  6587.         if (this.getEventInvitesDeltaList && this.getEventInvitesDeltaList.length > 0 && facebookAlertsManager.eventsEnabled)
  6588.             queriesStr.push("\"events\":\"SELECT eid,name,pic_big FROM event WHERE eid IN(" + this.getEventInvitesDeltaList.join(',') + ")\"");
  6589.         if (this.getFriendRequestsDeltaList && this.getFriendRequestsDeltaList.length > 0 && facebookAlertsManager.friendReqEnabled)
  6590.             queriesStr.push("\"users\":\"SELECT uid,name,pic_square FROM user WHERE uid IN(" + this.getFriendRequestsDeltaList.join(',') + ")\"");
  6591.  
  6592.         arrParams = this.createFacebookRequestPostParams('facebook.fql.multiquery', "{" + queriesStr.join(',') + "}");
  6593.         var self = this;
  6594.         if (queriesStr.length > 0) {
  6595.             oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams,
  6596.                                 function(strResponse, o, method) { self.onResponse(strResponse, o, method); }, 
  6597.                                 'facebook.fql.multiquery');
  6598.             EBServerDataURL.ServiceRequest(oRequest);
  6599.         }
  6600.  
  6601.         if (this.lastKnownUnreadMsgUpdateTime > -1 && facebookAlertsManager.inboxEnabled) {
  6602.             var queryStr = "SELECT uid,name,pic_square FROM user WHERE uid IN (SELECT snippet_author FROM thread WHERE folder_id=0 AND unread<>0 AND updated_time>" + this.lastKnownUnreadMsgUpdateTime + ")";
  6603.             arrParams = this.createFacebookRequestPostParams('facebook.fql.query', queryStr);
  6604.             oRequest = new FacebookRQ(facebookPrefFromSetting.facebookApiUrl, arrParams,
  6605.                                 function(strResponse, o, method) { self.onResponse(strResponse, o, method); },
  6606.                                 'facebook.fql.newMessages');
  6607.             EBServerDataURL.ServiceRequest(oRequest);
  6608.         }
  6609.     };
  6610.  
  6611.     this.RequestForLogout = function() {
  6612.         var self = this;
  6613.         var oRequest = new FacebookRQ(facebookPrefFromSetting.links.facebookLogoutUrl + "?api_key=" + FacebookXPCOM.consts.FB_APP_API_KEY + "&session_key=" + this.sessionKey, null,
  6614.                     function(strResponse, o, method) { self.onResponse(strResponse, o, method); },
  6615.                     "facebook.logout");
  6616.         EBServerDataURL.ServiceRequest(oRequest);
  6617.     };
  6618.  
  6619.     this.createFacebookRequestPostParams = function(method, text) {
  6620.         var arrParams = new Array();
  6621.         arrParams.push("api_key=" + FacebookXPCOM.consts.FB_APP_API_KEY);
  6622.         arrParams.push("v=" + FacebookXPCOM.consts.FB_API_VER);
  6623.         arrParams.push("method=" + method);
  6624.         arrParams.push("call_id=" + new Date().getTime());
  6625.         // if we have a stored token/session, use them
  6626.         if (this.token) arrParams.push("auth_token=" + this.token);
  6627.         if (this.sessionKey) arrParams.push("session_key=" + this.sessionKey);
  6628.         
  6629.         switch (method) {
  6630.             case "facebook.fql.query":
  6631.                 arrParams.push("query=" + text);
  6632.                 break;
  6633.             case "facebook.fql.multiquery":
  6634.                 arrParams.push("queries=" + text);
  6635.                 break;
  6636.             case "facebook.status.set":
  6637.                 arrParams.push("status=" + text);
  6638.                 break;
  6639.             case "facebook.users.hasAppPermission":
  6640.                 arrParams.push("ext_perm=" + text);
  6641.                 break;
  6642.         }
  6643.         
  6644.         arrParams.push("format=JSON");
  6645.         arrParams.sort();
  6646.         arrParams.push("sig=" + this.GetSignature(arrParams));
  6647.         arrParams.sort();
  6648.         
  6649.         return arrParams;
  6650.     };
  6651.     
  6652.     this.GetSignature = function(arrParams) {
  6653.         var params = arrParams.join("");
  6654.         params += (this.sessionSecret) ? this.sessionSecret : FacebookXPCOM.consts.FB_APP_SECRET;
  6655.         
  6656.         return MD5(params);
  6657.     };
  6658.  
  6659.     this.onResponse = function(strResponse, o, method) {
  6660.         switch (method) {
  6661.             case 'facebook.notifications.get':
  6662.                 break;
  6663.             case 'facebook.fql.newFeeds':
  6664.                 tmpDataForNewFeeds = strResponse;
  6665.                 this.handleNewFeedsResponse(strResponse);
  6666.                 break;
  6667.             case 'facebook.fql.usersForNewFeeds':
  6668.                 strResponse = "{\"feeds\":" + tmpDataForNewFeeds + " ,\"users\":" + strResponse + "}";
  6669.                 tmpDataForNewFeeds = "";
  6670.                 break;
  6671.             case 'facebook.fql.multiquery':
  6672.                 method = 'facebook.alerts.data';
  6673.                 break;
  6674.         }
  6675.  
  6676.         objCallback(strResponse, method);
  6677.     };
  6678.  
  6679.     this.handleNewFeedsResponse = function(jsonStr) {
  6680.         var jsonObj = JSON.parse(jsonStr);
  6681.         if (this.lastKnownUnreadFeedUpdateTime == -1) {
  6682.             this.lastKnownUnreadFeedUpdateTime = jsonObj[0].time;
  6683.         }
  6684.         else {
  6685.             var uidArray = new Array();
  6686.             if (jsonObj[0])
  6687.                 this.lastKnownUnreadFeedUpdateTime = jsonObj[0].time;
  6688.             for (var i = 0; i < jsonObj.length; i++)
  6689.                 uidArray.push(jsonObj[i].uid);
  6690.             if (uidArray.length > 0) {
  6691.                 var query = "SELECT uid,name, pic_square FROM user WHERE uid IN(" + uidArray.join(',') + ")";
  6692.                 this.Request('facebook.fql.query', query, 'facebook.fql.usersForNewFeeds');
  6693.             }
  6694.         }
  6695.     };
  6696. };
  6697.  
  6698. function FacebookSettingsManager(oPrefs, iIntervalSec, serviceUrl, locale, objCallback) {
  6699.     var timeoutRef = null;
  6700.  
  6701.     this._request = function() {
  6702.         var self = this;
  6703.         var objRequest = new FacebookSettingsRQ(this.getUrl(), locale, "2.5.2.14",
  6704.                                                 function(strResponse) { self.response(strResponse); });
  6705.  
  6706.         oPrefs.SetPref(FacebookXPCOM.consts.settingsLastCheckTime, Date());
  6707.         EBServerDataURL.ServiceRequest(objRequest);
  6708.     };
  6709.  
  6710.     this.request = function(bForce) {
  6711.         this.shutdown();
  6712.  
  6713.         var iTimeout = (bForce) ? 0 : this.getNextCheckInterval();
  6714.         var self = this;
  6715.         timeoutRef = setTimeout(function() { self._request(); }, iTimeout);
  6716.     };
  6717.  
  6718.     this.response = function(strResponse) {
  6719.         this.request(false);
  6720.  
  6721.         if (!strResponse) return;
  6722.  
  6723.         var xmlDoc = XML.GetXmlDocument(strResponse);
  6724.         if (!XML.IsLegal(xmlDoc)) return;
  6725.  
  6726.         objCallback(xmlDoc.documentElement, locale);
  6727.     };
  6728.  
  6729.     this.shutdown = function() {
  6730.         if (timeoutRef)
  6731.             clearTimeout(timeoutRef);
  6732.     };
  6733.     
  6734.     this.getUrl = function() {
  6735.         return serviceUrl ? serviceUrl : FacebookXPCOM.consts.settingsDefaultUrl;
  6736.     };
  6737.  
  6738.     this.getNextCheckInterval = function() {
  6739.         var lastCheck = oPrefs.GetPref(FacebookXPCOM.consts.settingsLastCheckTime);
  6740.         if (!lastCheck) return 0;
  6741.  
  6742.         var iLastCheck = Date.parse(lastCheck);
  6743.         if (!iLastCheck) return 0;
  6744.  
  6745.         var iNow = Date.parse(Date());
  6746.         var iNextCheck = iLastCheck + iIntervalSec * 1000 - iNow;
  6747.         if (iNextCheck < 0) iNextCheck = 0;
  6748.  
  6749.         return iNextCheck;
  6750.     };
  6751. };
  6752. function Fix404Obj(ctid, url, isEnabled, isExternal) {
  6753.     this.url = url;
  6754.     this.CTID = ctid;
  6755.     this.isEnabled = isEnabled;
  6756.     this.isExternal = isExternal;
  6757. };
  6758. function Fix404Manager() {
  6759.     var toolbarsHash = new HashArray();
  6760.  
  6761.     this.register = function(strCTID, strUrl, isEnabled, isExternal) {
  6762.         var objData = null;
  6763.         if (toolbarsHash.Contains(strCTID)) {
  6764.             objData = toolbarsHash.GetByID(strCTID);
  6765.             objData.isEnabled = isEnabled;
  6766.             objData.isExternal = isExternal;
  6767.             objData.url = strUrl;
  6768.         }
  6769.         else {
  6770.             objData = new Fix404Obj(strCTID, strUrl, isEnabled, isExternal);
  6771.             toolbarsHash.Add(strCTID, objData);
  6772.         }
  6773.     };
  6774.  
  6775.     this.setEnabledState = function(strCTID, isEnabled) {
  6776.         if (!toolbarsHash.Contains(strCTID)) return;
  6777.  
  6778.         var objData = toolbarsHash.GetByID(strCTID);
  6779.         objData.isEnabled = isEnabled;
  6780.     };
  6781.  
  6782.     this.getData = function() {
  6783.         var objData = null;
  6784.         for (var i = 0; i < toolbarsHash.Count(); i++) {
  6785.             objData = toolbarsHash.GetByIndex(i);
  6786.             if (objData.isEnabled) return objData;
  6787.         }
  6788.  
  6789.         return null;
  6790.     };
  6791.  
  6792.     this.on404 = function(aProgress, aRequest, aFlag, aStatus) {
  6793.         var objData = this.getData();
  6794.         if (!objData) return;
  6795.  
  6796.         var oWindow = aProgress.DOMWindow;
  6797.         var strRedirectUrl = objData.url.replace(/EB_MAIN_FRAME_URL/g, encodeURIComponent(oWindow.document.baseURI));
  6798.  
  6799.         var oCallback = function(strResponse) {
  6800.             //check if the page is legal
  6801.             if (strResponse.indexOf("<!--FIX_PAGE_NOT_FOUND_REMARK-->") == -1) return;
  6802.  
  6803.             if (objData.isExternal) {
  6804.                 try {
  6805.                     var iframe = oWindow.document.createElement("iframe");
  6806.                     iframe.setAttribute("style", "width:100%; height:100%; margin:0px; border:0px solid white");
  6807.                     var oBody = oWindow.document.getElementsByTagName("body")[0];
  6808.                     var oHead = oWindow.document.getElementsByTagName("head")[0];
  6809.                     if (oHead) oHead.innerHTML = "";
  6810.                     if (oBody) {
  6811.                         oBody.innerHTML = "";
  6812.                         oBody.style.margin = "0px";
  6813.                         oBody.style.padding = "0px";
  6814.                         oBody.appendChild(iframe);
  6815.                         iframe.src = strRedirectUrl;
  6816.                     }
  6817.                 }
  6818.                 catch (ex) {
  6819.                     Logging.LogToConsole(ex);
  6820.                 }
  6821.             }
  6822.             else {
  6823.                 try {
  6824.                     strResponse = strResponse.replace(/<!--FIX_PAGE_NOT_FOUND_REMARK-->/, '');
  6825.                     strResponse = strResponse.replace(/<!--/g, '');
  6826.                     strResponse = strResponse.replace(/-->/g, '');
  6827.                     strResponse = strResponse.replace(/\'/g, "\\'");
  6828.                     strResponse = strResponse.replace(/\r\n/g, "");
  6829.                     strResponse = strResponse.replace(/\/\/\<\!\[CDATA\[/g, '');
  6830.                     strResponse = strResponse.replace(/\/\/]]>/g, '');
  6831.  
  6832.                     var strJSInnerHTML = "document.write('" + strResponse + "'); document.close();";
  6833.  
  6834.                     var oScript = oWindow.document.createElement('script');
  6835.                     oScript.setAttribute('type', 'text/javascript');
  6836.                     oScript.innerHTML = strJSInnerHTML;
  6837.  
  6838.                     oWindow.document.getElementsByTagName('head')[0].appendChild(oScript);
  6839.                 }
  6840.                 catch (ex) {
  6841.                     Logging.LogToConsole(ex);
  6842.                 }
  6843.             }
  6844.         };
  6845.  
  6846.         try {
  6847.             aRequest.cancel(aRequest.NS_ERROR_FAILURE);
  6848.             EBServerDataURL.HTTPServerRequest(strRedirectUrl, null, false, oCallback, null, true);
  6849.         }
  6850.         catch (ex) {
  6851.             Logging.LogToConsole(ex);
  6852.         }
  6853.     };
  6854. };
  6855. var Fix404XPCOM =
  6856. {
  6857.     manager: new Fix404Manager()
  6858. };
  6859. function KeysStorageManager() {
  6860.     this.Data = new Array();
  6861.  
  6862.     this.storeKey = function(strCTID, strKey, strValue) {
  6863.         if (!this.Data[strCTID])
  6864.             this.Data[strCTID] = new Array();
  6865.  
  6866.         this.Data[strCTID][strKey] = strValue;
  6867.     };
  6868.  
  6869.     this.retrieveKey = function(strCTID, strKey) {
  6870.         return this.Data[strCTID][strKey];
  6871.     };
  6872.  
  6873.     this.deleteKey = function(strCTID, strKey) {
  6874.         delete this.Data[strCTID][strKey];
  6875.     };
  6876. };
  6877. var KeysStorageXPCOM =
  6878. {
  6879.     manager: new KeysStorageManager()
  6880. };
  6881.  
  6882. var SearchInNewTabConsts =
  6883. {
  6884.     htmlDataFile: "searchInNewTabData.xml"
  6885. };
  6886. var SearchInNewTabPrefConsts =
  6887. {
  6888.     LastCheckTime: "SearchInNewTabLastCheckTime",
  6889.     SearchInNewTabUserEnabled: "SearchInNewTabUserEnabled"
  6890. };
  6891. function SearchInNewTabRQ(serviceUrl, objCallback) {
  6892.     this.callback = objCallback;
  6893.     this.url = serviceUrl;
  6894.     this.postParams = "";
  6895. };
  6896. function SearchInNewTabRS(xmlNewTab) {
  6897.     this.script = "";
  6898.     this.html = "";
  6899.  
  6900.     this.parse = function() {
  6901.         for (var i = 0; i < xmlNewTab.childNodes.length; i++) {
  6902.             switch (xmlNewTab.childNodes[i].tagName) {
  6903.                 case "SCRIPT": this.script = XML.GetXmlNodeValue(xmlNewTab.childNodes[i]); break;
  6904.                 case "HTML": this.html = XML.GetXmlNodeValue(xmlNewTab.childNodes[i]); break;
  6905.             }
  6906.         }
  6907.     };
  6908.  
  6909.     this.toString = function() {
  6910.         return XML.GetStringXml(xmlNewTab);
  6911.     };
  6912.     
  6913.     if (xmlNewTab) this.parse();
  6914. };
  6915. function SearchInNewTabUsageRQ(serviceUrl, originalCTID, browserVersion, toolbarVersion, platform, toolbarAge, actionType) {
  6916.     var USAGE_RQ = "incomingUsersRequestXML=<HOSTING_USAGE_XML><MSG_TYPE>USER_USAGE_RQ</MSG_TYPE><MSG_XML><ORIGINAL_CT_ID>{0}</ORIGINAL_CT_ID><BROWSER_VERSION>{1}</BROWSER_VERSION><TOOLBAR_VERSION>{2}</TOOLBAR_VERSION><PLATFORM>{3}</PLATFORM><TOOLBAR_AGE_DAYS>{4}</TOOLBAR_AGE_DAYS><ACTION_TYPE>{5}</ACTION_TYPE></MSG_XML></HOSTING_USAGE_XML>";
  6917.     this.callback = null;
  6918.     this.url = serviceUrl;
  6919.     this.postParams = "";
  6920.  
  6921.     this._init = function() {
  6922.         this.postParams = stringFormat(USAGE_RQ, originalCTID, browserVersion, toolbarVersion, platform, toolbarAge, actionType);
  6923.     };
  6924.  
  6925.     this._init();
  6926. };
  6927. function SearchInNewTabManager(originalCTID, currentCTID, objToolbarDefaults, publisherServiceUrl, enabled) {
  6928.     var oPrefs = new PrefManager(originalCTID, currentCTID);
  6929.     var oIO = new IO(originalCTID, currentCTID);
  6930.     var serviceManager = null;
  6931.     var objXmlData = null;
  6932.  
  6933.     var _isEnabled = null;
  6934.     this.__defineSetter__("userEnabled", function(value) {
  6935.         oPrefs.SetPref(SearchInNewTabPrefConsts.SearchInNewTabUserEnabled, value);
  6936.         _isEnabled = value && enabled;
  6937.     });
  6938.  
  6939.     this.__defineGetter__("userEnabled", function() {
  6940.         return (oPrefs.HasUserValue(SearchInNewTabPrefConsts.SearchInNewTabUserEnabled)) ?
  6941.                             oPrefs.GetPref(SearchInNewTabPrefConsts.SearchInNewTabUserEnabled) : true;
  6942.     });
  6943.  
  6944.     this.__defineSetter__("isEnabled", function(value) { _isEnabled = value; });
  6945.  
  6946.     this.__defineGetter__("isEnabled", function() {
  6947.         return _isEnabled;
  6948.     });
  6949.  
  6950.     this.arrachEvents = function(DOMWindow) {
  6951.         DOMWindow.newTabEventsAttached = true;
  6952.         var oJS = getJSObjectFromWindow(DOMWindow);
  6953.         var that = this;
  6954.         if (oJS.ScriptHelper && oJS.ScriptHelper.NotifyClose) {
  6955.             
  6956.             oJS.ScriptHelper.NotifyClose = function(e) {
  6957.             oPrefs.SetPref(SearchInNewTabPrefConsts.SearchInNewTabUserEnabled, false);
  6958.                 that.userEnabled = false;
  6959.                 //send usage
  6960.                 if (oPrefs.GetPref(ToolbarPrefsConsts.EnableUsage, false, true))
  6961.                     SearchInNewTabUsage.closeSearchInNewTab(oPrefs, originalCTID, objToolbarDefaults.version);
  6962.             };
  6963.         }
  6964.  
  6965.         //return focus to url bar
  6966.         getWindow().gURLBar.focus();
  6967.     };
  6968.  
  6969.     this.onNewTabOpened = function(DOMWindow) {
  6970.         if (!objXmlData) return;
  6971.  
  6972.         var strUrl = stringFormat("chrome://{0}/content/{1}", objToolbarDefaults.chromeName, SearchInNewTabXPCOM.HTML_FILE_NAME);
  6973.         getWindow().gBrowser.loadURIWithFlags(strUrl, Components.interfaces.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null);
  6974.     };
  6975.  
  6976.     this.onWindowLoad = function(DOMWindow) {
  6977.         //messing with DOM causes another document complete event, so we need to set attribute to know that
  6978.         //DOM is already updated
  6979.         if (DOMWindow.newTabScriptInjected) {
  6980.             if (DOMWindow.newTabEventsAttached)
  6981.                 return;
  6982.             else
  6983.             //attach event that notifies toolbar that user doesn't wont to show newtab search box again
  6984.                 this.arrachEvents(DOMWindow);
  6985.             return;
  6986.         }
  6987.  
  6988.         DOMWindow.newTabScriptInjected = true;
  6989.         var doc = DOMWindow.document;
  6990.         var oScript = doc.createElement("script");
  6991.         oScript.setAttribute("type", "text/javascript");
  6992.         oScript.innerHTML = objXmlData.script;
  6993.         doc.getElementsByTagName("head")[0].appendChild(oScript);
  6994.  
  6995.         var oHtmlContainer = doc.body;
  6996.         oHtmlContainer.innerHTML = objXmlData.html;
  6997.  
  6998.         //send usage
  6999.         if (oPrefs.GetPref(ToolbarPrefsConsts.EnableUsage, false, true))
  7000.             SearchInNewTabUsage.newTab(oPrefs, originalCTID, objToolbarDefaults.version);
  7001.     };
  7002.  
  7003.     this.onServiceResponse = function(xmlResponse) {
  7004.         oIO.writeToolbarFile(XML.GetStringXml(xmlResponse), SearchInNewTabConsts.htmlDataFile, true);
  7005.         objXmlData = new SearchInNewTabRS(xmlResponse.documentElement);
  7006.     };
  7007.  
  7008.     this.loadData = function() {
  7009.         var strData = oIO.readToolbarFile(SearchInNewTabConsts.htmlDataFile, true);
  7010.         if (!strData) return;
  7011.  
  7012.         var xmlData = XML.GetXmlDocument(strData);
  7013.         if (!XML.IsLegal(xmlData)) return;
  7014.  
  7015.         objXmlData = new SearchInNewTabRS(xmlData.documentElement);
  7016.     };
  7017.  
  7018.     this.init = function() {
  7019.         var isUserEnabled = (oPrefs.HasUserValue(SearchInNewTabPrefConsts.SearchInNewTabUserEnabled)) ?
  7020.                                 oPrefs.GetPref(SearchInNewTabPrefConsts.SearchInNewTabUserEnabled) : true;
  7021.         this.isEnabled = isUserEnabled && enabled;
  7022.  
  7023.         this.loadData();
  7024.         var strServiceUrl = (publisherServiceUrl) ? publisherServiceUrl : oPrefs.GetPref(LoginPrefConsts.SearchInNewTabServiceUrl);
  7025.         //replace aliases
  7026.         strServiceUrl = strServiceUrl.replace(/EB_TOOLBAR_ID/g, currentCTID);
  7027.         serviceManager = new SearchInNewTabServiceManager(strServiceUrl, oPrefs, this.onServiceResponse, this);
  7028.         serviceManager.request();
  7029.     };
  7030.  
  7031.     this.shutdown = function() {
  7032.         if (serviceManager) serviceManager.shutdown();
  7033.     };
  7034.     
  7035.     this.init();
  7036. };
  7037. function SearchInNewTabServiceManager(strServiceUrl, oPrefs, objCallback, objCallbackThis) {
  7038.     var DEFAULT_INTERVAL_MM = 1440;
  7039.     var timeoutRef = null;
  7040.  
  7041.     this.request = function() {
  7042.         var iTimeout = this._getNextCheckInterval();
  7043.         var self = this;
  7044.         var request = function() {
  7045.             oPrefs.SetPref(SearchInNewTabPrefConsts.LastCheckTime, Date(), true);
  7046.             var oRequest = new SearchInNewTabRQ(strServiceUrl, function(strResponse) { self.onResponse(strResponse); });
  7047.             EBServerDataURL.ServiceRequest(oRequest);
  7048.         };
  7049.  
  7050.         timeoutRef = setTimeout(request, iTimeout);
  7051.     };
  7052.  
  7053.     this.shutdown = function() {
  7054.         clearTimeout(timeoutRef);
  7055.     };
  7056.  
  7057.     this.reInit = function() {
  7058.         this.shutdown();
  7059.         this.request();
  7060.     };
  7061.  
  7062.     this.onResponse = function(strResponse) {
  7063.         //set new request
  7064.         this.request();
  7065.         var xmlResponse = XML.GetXmlDocument(strResponse);
  7066.         if (!XML.IsLegal(xmlResponse)) return;
  7067.         
  7068.         objCallback.call(objCallbackThis, xmlResponse);
  7069.     };
  7070.     
  7071.     this._getNextCheckInterval = function() {
  7072.         //no last check time
  7073.         var strLastCheckTime = oPrefs.GetPref(SearchInNewTabPrefConsts.LastCheckTime, true);
  7074.         if (!strLastCheckTime) return 0;
  7075.  
  7076.         var iCheckIntervalMM = (oPrefs.HasUserValue(LoginPrefConsts.SearchInNewTabIntervalMM)) ?
  7077.                                     oPrefs.GetPref(LoginPrefConsts.SearchInNewTabIntervalMM) : DEFAULT_INTERVAL_MM;
  7078.  
  7079.         var iLastCheckTime = Date.parse(strLastCheckTime);
  7080.         var iNow = Date.parse(Date());
  7081.  
  7082.         //time to check
  7083.         var nextCheck = (iLastCheckTime + iCheckIntervalMM * 60 * 1000) - iNow;
  7084.         return (nextCheck < 0) ? 0 : nextCheck;
  7085.     };
  7086. };
  7087. var SearchInNewTabUsage = {
  7088.     newTab: function(oPrefs, originalCTID, toolbarVersion) {
  7089.         var usageServiceUrl = oPrefs.GetPref(LoginPrefConsts.SearchInNewTabUsageUrl);
  7090.         var browserVersion = AppInfo.browserVersion;
  7091.         var platform = "FF";
  7092.         var actionType = "NEW_TAB";
  7093.         var toolbarAge = ToolbarFunctions.getToolbarAgeInDays(oPrefs);
  7094.         var usageRQ = new SearchInNewTabUsageRQ(usageServiceUrl, originalCTID, browserVersion, toolbarVersion, platform, toolbarAge, actionType);
  7095.         EBServerDataURL.ServiceRequest(usageRQ);
  7096.     },
  7097.  
  7098.     closeSearchInNewTab: function(oPrefs, originalCTID, toolbarVersion) {
  7099.         var usageServiceUrl = oPrefs.GetPref(LoginPrefConsts.SearchInNewTabUsageUrl);
  7100.         var browserVersion = AppInfo.browserVersion;
  7101.         var platform = "FF";
  7102.         var actionType = "NEW_TAB_DISABLED";
  7103.         var toolbarAge = ToolbarFunctions.getToolbarAgeInDays(oPrefs);
  7104.         var usageRQ = new SearchInNewTabUsageRQ(usageServiceUrl, originalCTID, browserVersion, toolbarVersion, platform, toolbarAge, actionType);
  7105.         EBServerDataURL.ServiceRequest(usageRQ);
  7106.     }
  7107. };
  7108. var SearchInNewTabXPCOM =
  7109. {
  7110.     HTML_FILE_NAME: "aboutTabs.htm",
  7111.  
  7112.     hashManagers: new HashArray2(),
  7113.  
  7114.     register: function(originalCTID, currentCTID, objToolbarDefaults, publisherServiceUrl, enabled) {
  7115.         var manager = new SearchInNewTabManager(originalCTID, currentCTID, objToolbarDefaults, publisherServiceUrl, enabled);
  7116.  
  7117.         if (this.hashManagers.Contains(originalCTID)) {
  7118.             var oldManager = this.hashManagers.GetByID(originalCTID);
  7119.             oldManager.shutdown();
  7120.             this.hashManagers.Add(originalCTID, manager);
  7121.         }
  7122.         else
  7123.             this.hashManagers.Add(originalCTID, manager);
  7124.     },
  7125.  
  7126.     getManager: function(originalCTID) {
  7127.         if (this.hashManagers.Contains(originalCTID))
  7128.             return this.hashManagers.GetByID(originalCTID);
  7129.         else {
  7130.             EBLog("search in new tab manager not found");
  7131.             return null;
  7132.         }
  7133.     },
  7134.  
  7135.     getActiveManager: function() {
  7136.         if (this.hashManagers.Count() == 0) return null;
  7137.  
  7138.         var manager = null;
  7139.         for (var i = 0; i < this.hashManagers.Count(); i++) {
  7140.             manager = this.hashManagers.GetByIndex(i);
  7141.             if (manager.isEnabled)
  7142.                 return manager;
  7143.         }
  7144.  
  7145.         return null;
  7146.     },
  7147.  
  7148.     onNewTabOpened: function(DOMWindow) {
  7149.         var manager = this.getActiveManager();
  7150.         if (!manager) return;
  7151.  
  7152.         manager.onNewTabOpened(DOMWindow);
  7153.     },
  7154.  
  7155.     isNewTabDocument: function(strUrl) {
  7156.         return (strUrl.indexOf("chrome://") == 0 && strUrl.indexOf(this.HTML_FILE_NAME) != -1);
  7157.     },
  7158.  
  7159.     onDocumentLoaded: function(DOMWindow) {
  7160.         var strUrl = DOMWindow.document.location.href;
  7161.         if (!this.isNewTabDocument(strUrl)) return;
  7162.  
  7163.         var manager = this.getActiveManager();
  7164.         if (!manager) return;
  7165.  
  7166.         manager.onWindowLoad(DOMWindow);
  7167.     }
  7168. };
  7169. var ClientLogXPCOM =
  7170. {
  7171.     event: ClientLogEvent,
  7172.     toolbarInfo: ClientLogToolbarInfo,
  7173.     manager: new ClientLogManager()
  7174. };
  7175.  
  7176.  
  7177. var ClientLogConsts =
  7178. {
  7179.     defaultServiceUrl: "http://clientlog.users.conduit.com/ClientDiagnostics.asmx/ReportDiagnosticsEvent"
  7180. };
  7181. var ClientLogPrefConsts =
  7182. {
  7183.     serviceUrl: "clientLogServiceUrl",
  7184.     isEnabled: "clientLogIsEnabled"
  7185. }
  7186.  
  7187. function ClientLogEvent(id, eventType, message, data) {
  7188.     this.id = id;
  7189.     this.eventType = eventType;
  7190.     this.message = XML.ToLegalXML(message);
  7191.     this.data = data;
  7192. };
  7193. function ClientLogToolbarInfo(version, originalCTID, actingCTID, os, browser) {
  7194.     this.version = version;
  7195.     this.originalCTID = originalCTID;
  7196.     this.platform = "FF";
  7197.     this.os = os;
  7198.     this.browser = XML.ToLegalXML(browser);
  7199.     this.ctid = actingCTID;
  7200. };
  7201. function ClientLogManager() {
  7202.     this.onLoginResponse = function(xmlClientLog, strOriginalCTID) {
  7203.         if (!xmlClientLog) return;
  7204.  
  7205.         var bIsEnabled = XML.GetSingleNodeValueAsBoolean(xmlClientLog, "ENABLED", false);
  7206.         var strSerivceUrl = XML.GetSingleNodeValue(xmlClientLog, "SERVICE_URL");
  7207.         this._updateServiceUrl(strOriginalCTID, strSerivceUrl, bIsEnabled);
  7208.     };
  7209.  
  7210.     this.send = function(objToolbarInfo, objEvent) {
  7211.         if (!this._isEnabled(objToolbarInfo.originalCTID)) return;
  7212.  
  7213.         var strServiceUrl = this._getServiceUrl(objToolbarInfo.originalCTID);
  7214.         var objMessage = new ClientLogRQ(strServiceUrl, objToolbarInfo, objEvent);
  7215.         EBServerDataURL.ServiceRequest(objMessage);
  7216.     };
  7217.  
  7218.     this._updateServiceUrl = function(strCTID, strServiceUrl, isEnabled) {
  7219.         var strPrefName = strCTID + "." + ClientLogPrefConsts.serviceUrl;
  7220.         PrefService.SetPref(strPrefName, strServiceUrl);
  7221.         strPrefName = strCTID + "." + ClientLogPrefConsts.isEnabled;
  7222.         PrefService.SetPref(strPrefName, isEnabled);
  7223.     };
  7224.  
  7225.     this._isEnabled = function(strCTID) {
  7226.         var strPrefName = strCTID + "." + ClientLogPrefConsts.isEnabled;
  7227.         if (!PrefService.HasUserValue(strPrefName))
  7228.             return true;
  7229.         else
  7230.             return PrefService.GetPref(strPrefName);
  7231.     };
  7232.  
  7233.     this._getServiceUrl = function(strCTID) {
  7234.         var strPrefName = strCTID + "." + ClientLogPrefConsts.serviceUrl;
  7235.         if (!PrefService.HasUserValue(strPrefName))
  7236.             return ClientLogConsts.defaultServiceUrl;
  7237.         else
  7238.             return PrefService.GetPref(strPrefName);
  7239.     };
  7240. };
  7241. function ClientLogRQ(serviceUrl, objToolbarInfo, objEvent) {
  7242.     var CLIENT_LOG_RQ = "<USERS_LOG_REQUEST><TOOLBAR_INFO><TOOLBAR_VERSION>{0}</TOOLBAR_VERSION><CTID>{1}</CTID><PLATFORM>{2}</PLATFORM><BROWSER_VERSION>{3}</BROWSER_VERSION><OPERATING_SYSTEM>{4}</OPERATING_SYSTEM><ACTING_CTID>{5}</ACTING_CTID></TOOLBAR_INFO><EVENT><ID>{6}</ID><TYPE>{7}</TYPE><MESSAGE>{8}</MESSAGE><DATA>{9}</DATA></EVENT></USERS_LOG_REQUEST>";
  7243.     var POST_PARAM = "RequestString=";
  7244.     this.callback = null;
  7245.     this.url = serviceUrl;
  7246.     this.postParams = "";
  7247.  
  7248.     this._init = function() {
  7249.         var strPostParam = stringFormat(CLIENT_LOG_RQ,
  7250.                                         objToolbarInfo.version,
  7251.                                         objToolbarInfo.originalCTID,
  7252.                                         objToolbarInfo.platform,
  7253.                                         objToolbarInfo.browser,
  7254.                                         objToolbarInfo.os,
  7255.                                         objToolbarInfo.ctid,
  7256.                                         objEvent.id,
  7257.                                         objEvent.eventType,
  7258.                                         objEvent.message,
  7259.                                         objEvent.data);
  7260.         this.postParams = POST_PARAM + encodeURIComponent(strPostParam);
  7261.     };
  7262.  
  7263.     this._init();  
  7264.  
  7265. }; 
  7266. var LanguagePackPrefConsts =
  7267. {
  7268.     LanguagePackLastCheckTime: "LanguagePackLastCheckTime",
  7269.     ToolbarLocale: "Locale"
  7270. };
  7271. function LanguagePackManager(defaultServiceUrl, originalCTID, actingCTID, version, oPrefs, callback, callbackThis) {
  7272.  
  7273.     this.request = function(bForce, lastUpdateTime) {
  7274.         var bIsTimeElased = this._isTimeElapse();
  7275.         if (!bIsTimeElased && !bForce) return;
  7276.  
  7277.         if (!lastUpdateTime) lastUpdateTime = 0;
  7278.         if (bForce) lastUpdateTime = 0;
  7279.         var locale = oPrefs.GetPref(SettingsPrefConsts.ToolbarLocale, true);
  7280.         //didn't receive settings yet
  7281.         if (!locale) return;
  7282.  
  7283.         //request LP
  7284.         var self = this;
  7285.         var oRequest = new LanguagePackRQ(this._getUrl(), actingCTID, version, locale, lastUpdateTime, LanguagePackDefaults.terms.KeysArray,
  7286.            function(strLP) { self.onResponse(strLP); });
  7287.         
  7288.         EBServerDataURL.ServiceRequest(oRequest);
  7289.     };
  7290.  
  7291.     this.shutdown = function() {
  7292.         //insert self clean up logic here
  7293.     };
  7294.  
  7295.     this.onResponse = function(strLP) {
  7296.         var xmlElem = ServerMessagesFunctions.getMessageXML(strLP);
  7297.         if (xmlElem) {
  7298.             var lpRS = new LanguagePackRS(xmlElem);
  7299.             this.saveLP(lpRS);
  7300.         }
  7301.     };
  7302.  
  7303.     this.saveLP = function(lpRS) {
  7304.         //save last check time
  7305.         oPrefs.SetPref(LanguagePackPrefConsts.LanguagePackLastCheckTime, Date(), true);
  7306.         //wrong locale
  7307.         var locale = oPrefs.GetPref(SettingsPrefConsts.ToolbarLocale, true);
  7308.         if (locale != lpRS.locale) return;
  7309.         if (!lpRS.isModified) return;
  7310.  
  7311.         callback.call(callbackThis, lpRS.xmlLP);
  7312.     };
  7313.  
  7314.     this._getUrl = function() {
  7315.         var strUrl = oPrefs.GetPref(LoginPrefConsts.LanguagePackServiceUrl, true);
  7316.         if (!strUrl) strUrl = defaultServiceUrl;
  7317.  
  7318.         return strUrl;
  7319.     };
  7320.  
  7321.     this._isTimeElapse = function() {
  7322.         //no last check time
  7323.         var strLastCheckTime = oPrefs.GetPref(LanguagePackPrefConsts.LanguagePackLastCheckTime, true);
  7324.         if (!strLastCheckTime) return true;
  7325.  
  7326.         //no interval
  7327.         var iCheckInterval = oPrefs.GetPref(LoginPrefConsts.LanguagePackReloadIntervalMM, false);
  7328.         if (!iCheckInterval) return true;
  7329.         
  7330.         var iLastCheckTime = Date.parse(strLastCheckTime);
  7331.         var iNow = Date.parse(Date());
  7332.  
  7333.         //time to check
  7334.         if (iLastCheckTime + iCheckInterval * 60 * 1000 <= iNow)
  7335.             return true;
  7336.  
  7337.         return false;
  7338.     };
  7339. };
  7340. function LanguagePackRQ(serviceUrl, actingCTID, version, locale, lastUpdateTime, arrKeys, objCallback) {
  7341.     var LP_RQ = "<EBXML><EBMSGID>CT_TRANSLATION_PACK_RQ</EBMSGID><EBMSG><CT_ID>{0}</CT_ID><VERSION>{1}</VERSION><LOCALE>{2}</LOCALE><LAST_UPDATE_TIME>{3}</LAST_UPDATE_TIME><TRANSLATION_KEYS>{4}</TRANSLATION_KEYS></EBMSG></EBXML>";
  7342.     var POST_PARAM = "RequestString=";
  7343.  
  7344.     this.callback = objCallback;
  7345.     this.url = serviceUrl;
  7346.     this.postParams = "";
  7347.  
  7348.     this._getKeysXmlString = function() {
  7349.         var strKeys = "";
  7350.         for (var i = 0; i < arrKeys.length; i++)
  7351.             strKeys += XML.CreateXmlNodeString("KEY_ID", arrKeys[i]);
  7352.  
  7353.         return strKeys;
  7354.     };
  7355.  
  7356.     this._init = function() {
  7357.         var strKeysXml = this._getKeysXmlString();
  7358.         var strPostParam = stringFormat(LP_RQ, actingCTID, version, locale, lastUpdateTime, strKeysXml);
  7359.         this.postParams = POST_PARAM + encodeURIComponent(strPostParam);
  7360.     };
  7361.  
  7362.     this._init();
  7363. };
  7364. function LanguagePackRS(xmlLP) {
  7365.     this.lastUpdateTime = "";
  7366.     this.locale = "";
  7367.     this.xmlTranslatedKeys = null;
  7368.     this.isModified = true;
  7369.     this.xmlLP = xmlLP;
  7370.  
  7371.     this.parse = function() {
  7372.         this.lastUpdateTime = XML.GetSingleNodeValue(xmlLP, "LAST_UPDATE_TIME");
  7373.         this.locale = XML.GetSingleNodeValue(xmlLP, "LOCALE");
  7374.         this.xmlTranslatedKeys = XML.SelectSingleNode(xmlLP, "TRANSLATED_KEYS");
  7375.     };
  7376.  
  7377.     this.checkIfModified = function() {
  7378.         if (this.xmlTranslatedKeys &&
  7379.             this.xmlTranslatedKeys.childNodes.length == 1 &&
  7380.             XML.GetXmlNodeValue(this.xmlTranslatedKeys) == "NOT MODIFIED")
  7381.  
  7382.             this.isModified = false;
  7383.     };
  7384.  
  7385.     if (xmlLP) {
  7386.         this.parse();
  7387.         this.checkIfModified();
  7388.     }
  7389. };
  7390. var LoginPrefConsts =
  7391. {
  7392.     LastLoginDate: "LastLogin_2.5.2.14",
  7393.     LoginCache: "LoginCache",
  7394.     UserID : "UserID",
  7395.  
  7396.     GroupingServerCheckInterval: "GroupingServerCheckInterval",
  7397.     GroupingServiceUrl: "GroupingServiceUrl",
  7398.     
  7399.     AboutPrivacyUrl: "AboutPrivacyUrl",
  7400.     TrusteLinkUrl: "TrusteLinkUrl",
  7401.     UsageServerURL: "UsageServerURL",
  7402.  
  7403.     FirstTime: "FirstTime",
  7404.     LanguagePackServiceUrl: "LanguagePackServiceUrl",
  7405.     LanguagePackReloadIntervalMM: "LanguagePackReloadIntervalMM",
  7406.     
  7407.     MyStuffServiceUrl: "myStuffServiceUrl",
  7408.     MyStuffServiceIntervalMM: "myStuffServiceIntervalMM",
  7409.     MyStuffSearchUrl: "myStuffSearchUrl",
  7410.     MyStuffEnabled: "myStuffEnabled",
  7411.     MyStuffPublihserMinWidth: "myStuffPublihserMinWidth",
  7412.     
  7413.     LatestVersion: "LatestVersion",
  7414.     ValidationData_Search: "ValidationData_Search",
  7415.     ValidationData_Toolbar: "ValidationData_Toolbar",
  7416.     
  7417.     //search in new tab
  7418.     SearchInNewTabServiceUrl: "SearchInNewTabServiceUrl",
  7419.     SearchInNewTabIntervalMM: "SearchInNewTabIntervalMM",
  7420.     SearchInNewTabUsageUrl: "SearchInNewTabUsageUrl",
  7421.     SearchInNewTabEnabled: "SearchInNewTabEnabled",
  7422.     
  7423.     FirstServerDate: "FirstServerDate",
  7424.     CurrentServerDate: "CurrentServerDate"
  7425. };
  7426. function LoginManager(defaultServiceUrl, originalCTID, actingCTID, oPrefs, objToolbarDefaults, refreshCallback, refreshCallbackThis) {
  7427.     var UN = "UN";
  7428.     var UNIQUE_ID_LENGTH = 19;
  7429.     var SERVER_POST_FIX = "/iis2ebs.asp";
  7430.     var DEFAULT_LOGIN_CACHE = 4;
  7431.     var timeoutFunct = null;
  7432.  
  7433.     this._request = function() {
  7434.         var os = AppInfo.getOS();
  7435.         var browserVersion = AppInfo.xulRuntime.version;
  7436.         var platform = AppInfo.xulRuntime.name.toUpperCase();
  7437.         var version = objToolbarDefaults.version;
  7438.         var objValidationData = null;
  7439.         if (objToolbarDefaults.sendValidationData) {
  7440.             objValidationData = new Object();
  7441.             objValidationData.isFirst = !oPrefs.HasUserValue(LoginPrefConsts.LastLoginDate);
  7442.             objValidationData.search = (oPrefs.HasUserValue(LoginPrefConsts.ValidationData_Search)) ?
  7443.                                             oPrefs.GetPref(LoginPrefConsts.ValidationData_Search) : 0;
  7444.             objValidationData.toolbar = (oPrefs.HasUserValue(LoginPrefConsts.ValidationData_Toolbar)) ?
  7445.                                             oPrefs.GetPref(LoginPrefConsts.ValidationData_Toolbar) : 0;
  7446.             objValidationData.isUsageEnabled = (oPrefs.HasUserValue(ToolbarPrefsConsts.EnableUsage)) ?
  7447.                                             oPrefs.GetPref(ToolbarPrefsConsts.EnableUsage) : true;
  7448.         }
  7449.  
  7450.         var self = this;
  7451.         var oRequest = new LoginRQ(this._getUrl(), originalCTID, this.getUserID(), version, os, platform, 
  7452.                                     browserVersion, actingCTID, objValidationData,
  7453.                                     function(strLogin) { self.onResponse(strLogin); });
  7454.         EBServerDataURL.ServiceRequest(oRequest);
  7455.     };
  7456.  
  7457.     this.request = function(bForce) {
  7458.         //do not login until user sets the personal components dialog
  7459.         var notFirstTime = oPrefs.GetPref(LoginPrefConsts.FirstTime, false);
  7460.         if (!notFirstTime) return;
  7461.  
  7462.         var nextCheckInterval = (bForce) ? 0 : this._getNextCheckInterval();
  7463.         var self = this;
  7464.         timeoutFunct = setTimeout(function() { self._request(); }, nextCheckInterval);
  7465.     };
  7466.  
  7467.     this.shutdown = function() {
  7468.         clearTimeout(timeoutFunct);
  7469.     };
  7470.  
  7471.     this.onResponse = function(strLogin) {
  7472.         var xmlElem = ServerMessagesFunctions.getMessageXML(strLogin);
  7473.         var isFirstTime = false;
  7474.         if (xmlElem) {
  7475.             var loginRS = new LoginRS(xmlElem);
  7476.             isFirstTime = this.saveLogin(loginRS);
  7477.         }
  7478.         //if login previously done, still update the check time to now
  7479.         else {
  7480.             if (oPrefs.HasUserValue(LoginPrefConsts.LastLoginDate, false))
  7481.                 oPrefs.SetPref(LoginPrefConsts.LastLoginDate, Date(), false);
  7482.         }
  7483.  
  7484.         if (isFirstTime)
  7485.             refreshCallback.call(refreshCallbackThis);
  7486.  
  7487.         this.request(false);
  7488.     };
  7489.  
  7490.     this.saveLogin = function(loginRS) {
  7491.         ClientLogXPCOM.manager.onLoginResponse(loginRS.xmlClientLog, originalCTID);
  7492.         UninstallLogXPCOM.manager.onLoginResponse(loginRS.xmlUninstallLog, originalCTID);
  7493.  
  7494.         if (loginRS.LPServiceUrl) oPrefs.SetPref(LoginPrefConsts.LanguagePackServiceUrl, loginRS.LPServiceUrl);
  7495.         if (loginRS.LPIntervalMM) oPrefs.SetPref(LoginPrefConsts.LanguagePackReloadIntervalMM, loginRS.LPIntervalMM);
  7496.  
  7497.         //update last check time to now
  7498.         var bIsFirstTime = !oPrefs.HasUserValue(LoginPrefConsts.LastLoginDate);
  7499.         oPrefs.SetPref(LoginPrefConsts.LastLoginDate, Date(), false);
  7500.  
  7501.         //login cache
  7502.         if (oPrefs.HasUserValue(LoginPrefConsts.LoginCache, false))
  7503.             oPrefs.Clear(LoginPrefConsts.LoginCache, false);
  7504.         oPrefs.SetPref(LoginPrefConsts.LoginCache, loginRS.loginCache, false);
  7505.  
  7506.         //grouping
  7507.         if (loginRS.groupingInterval != 0 && loginRS.groupingInterval >= 30 && loginRS.groupingInterval <= 10080)
  7508.             oPrefs.SetPref(LoginPrefConsts.GroupingServerCheckInterval, loginRS.groupingInterval, false);
  7509.  
  7510.         if (loginRS.groupingServerUrl) oPrefs.SetPref(LoginPrefConsts.GroupingServiceUrl, loginRS.groupingServerUrl, false);
  7511.         //privacy url
  7512.         if (loginRS.privacyUrl) oPrefs.SetPref(LoginPrefConsts.AboutPrivacyUrl, loginRS.privacyUrl, false);
  7513.         //truste link url
  7514.         if (loginRS.trusteUrl) oPrefs.SetPref(LoginPrefConsts.TrusteLinkUrl, loginRS.trusteUrl, false);
  7515.         //usage service url
  7516.         if (loginRS.usageUrl) oPrefs.SetPref(LoginPrefConsts.UsageServerURL, loginRS.usageUrl, false);
  7517.  
  7518.         //mystuff
  7519.         if (loginRS.myStuffUrl) oPrefs.SetPref(LoginPrefConsts.MyStuffServiceUrl, loginRS.myStuffUrl, false);
  7520.         if (loginRS.myStuffIntervalMM) oPrefs.SetPref(LoginPrefConsts.MyStuffServiceIntervalMM, loginRS.myStuffIntervalMM, false);
  7521.         if (loginRS.myStuffSearchUrl) oPrefs.SetPref(LoginPrefConsts.MyStuffSearchUrl, loginRS.myStuffSearchUrl, false);
  7522.         if (loginRS.myStuffPublisherMinWidth) oPrefs.SetPref(LoginPrefConsts.MyStuffPublihserMinWidth, loginRS.myStuffPublisherMinWidth, false);
  7523.         oPrefs.SetPref(LoginPrefConsts.MyStuffEnabled, loginRS.myStuffEnabled, false);
  7524.  
  7525.         //trusted api domains
  7526.         if (loginRS.trustedApiDomains.length > 0)
  7527.             ToolbarManagerXPCOM.trustedDomains.saveTrustedDomains(loginRS.trustedApiDomains, originalCTID);
  7528.  
  7529.         //latest version
  7530.         if (loginRS.latestVersion) oPrefs.SetPref(LoginPrefConsts.LatestVersion, loginRS.latestVersion, false);
  7531.  
  7532.         //search in new tab
  7533.         if (loginRS.searchInNewTabServiceUrl) oPrefs.SetPref(LoginPrefConsts.SearchInNewTabServiceUrl, loginRS.searchInNewTabServiceUrl, false);
  7534.         if (loginRS.searchInNewTabIntervalMM) oPrefs.SetPref(LoginPrefConsts.SearchInNewTabIntervalMM, loginRS.searchInNewTabIntervalMM, false);
  7535.         if (loginRS.searchInNewTabUsageUrl) oPrefs.SetPref(LoginPrefConsts.SearchInNewTabUsageUrl, loginRS.searchInNewTabUsageUrl, false);
  7536.         oPrefs.SetPref(LoginPrefConsts.SearchInNewTabEnabled, loginRS.searchInNewTabEnabled, false);
  7537.  
  7538.         //handle server date
  7539.         if (loginRS.serverDate) {
  7540.             //set the first time only if didn't set before.
  7541.             if (!oPrefs.HasUserValue(LoginPrefConsts.FirstServerDate))
  7542.                 oPrefs.SetPref(LoginPrefConsts.FirstServerDate, loginRS.serverDate);
  7543.  
  7544.             oPrefs.SetPref(LoginPrefConsts.CurrentServerDate, loginRS.serverDate);
  7545.         }
  7546.  
  7547.         return bIsFirstTime;
  7548.     };
  7549.  
  7550.     this._getUrl = function() {
  7551.         var strUrl = oPrefs.GetPref(SettingsPrefConsts.ServerURL, false);
  7552.         if (!strUrl) strUrl = defaultServiceUrl;
  7553.  
  7554.         return strUrl + SERVER_POST_FIX;
  7555.     };
  7556.  
  7557.     this._getNextCheckInterval = function() {
  7558.         //no last check time
  7559.         var strLastCheckTime = oPrefs.GetPref(LoginPrefConsts.LastLoginDate, false);
  7560.         if (!strLastCheckTime) return 0;
  7561.         
  7562.         //no interval
  7563.         var iCheckInterval = (oPrefs.HasUserValue(LoginPrefConsts.LoginCache)) ?
  7564.                                     oPrefs.GetPref(LoginPrefConsts.LoginCache) : DEFAULT_LOGIN_CACHE;
  7565.  
  7566.         var iLastCheckTime = Date.parse(strLastCheckTime);
  7567.         var iNow = Date.parse(Date());
  7568.  
  7569.         //time to check
  7570.         var nextCheck = (iLastCheckTime + iCheckInterval * 60 * 60 * 1000) - iNow;
  7571.         if (nextCheck < 0)
  7572.             nextCheck = 0;
  7573.  
  7574.         return nextCheck;
  7575.     };
  7576.  
  7577.     this.getUserID = function() {
  7578.         var strUserId;
  7579.         //get it from preference
  7580.         strUserId = oPrefs.GetPref(LoginPrefConsts.UserID);
  7581.         if (!strUserId || strUserId.length != UNIQUE_ID_LENGTH) {
  7582.             strUserId = this._generateUserID();
  7583.             //save it to pref
  7584.             oPrefs.SetPref(LoginPrefConsts.UserID, strUserId, false);
  7585.         }
  7586.  
  7587.         return strUserId;
  7588.     };
  7589.  
  7590.     this._generateUserID = function() {
  7591.         var strID = UN + Math.random().toString().substring(2);
  7592.         while (strID.length < UNIQUE_ID_LENGTH)
  7593.             strID += Math.random().toString().substring(2);
  7594.  
  7595.         return strID.substr(0, 19);
  7596.     };
  7597. };
  7598. function LoginRQ(serviceUrl, originalCTID, userID, version, os, platform, browserVersion, actingCTID, objValidationData, objCallback) {
  7599.     var LOGIN_RQ = "<EBXML><EBMSGID>CT_LOGIN_RQ</EBMSGID><EBMSG><CT_ID>{0}</CT_ID><USERID>{1}</USERID><VERSION>{2}</VERSION><OPERATING_SYSTEM>{3}</OPERATING_SYSTEM><TIMESTAMP>{4}</TIMESTAMP><PLATFORM>{5}</PLATFORM><BROWSER_VERSION>{6}</BROWSER_VERSION><ACTING_CT_ID>{7}</ACTING_CT_ID>{8}</EBMSG></EBXML>";
  7600.     var VALIDATION_DATA = "<VALIDATION_DATA><SEARCH>{0}</SEARCH><TOOLBAR>{1}</TOOLBAR><IS_FIRST>{2}</IS_FIRST><IS_USAGE_LOGGING_ENABLED>{3}</IS_USAGE_LOGGING_ENABLED></VALIDATION_DATA>";
  7601.     var POST_PARAM = "RequestString=";
  7602.  
  7603.     this.callback = objCallback;
  7604.     this.url = serviceUrl;
  7605.     this.postParams = "";
  7606.  
  7607.     this.generateTimeStamp = function() {
  7608.         var strTimeStamp = "";
  7609.  
  7610.         var dateObj = new Date();
  7611.  
  7612.         var strMonth = "";
  7613.         var iMonth = dateObj.getMonth();
  7614.         iMonth++;
  7615.         strMonth = iMonth < 10 ? "0" + iMonth : iMonth;
  7616.  
  7617.         var strDay = "";
  7618.         var iDay = dateObj.getDate();
  7619.         strDay = iDay < 10 ? "0" + iDay : iDay;
  7620.  
  7621.         var strYear = dateObj.getFullYear();
  7622.  
  7623.         var strHour = "";
  7624.         var iHour = dateObj.getHours();
  7625.         strHour = iHour < 10 ? "0" + iHour : iHour;
  7626.  
  7627.         var strMinute = "";
  7628.         var iMinute = dateObj.getMinutes();
  7629.         strMinute = iMinute < 10 ? "0" + iMinute : iMinute;
  7630.  
  7631.         var strSecond = "";
  7632.         var iSecond = dateObj.getSeconds();
  7633.         strSecond = iSecond < 10 ? "0" + iSecond : iSecond;
  7634.  
  7635.         strTimeStamp = strMonth.toString() + "-" +
  7636.                     strDay.toString() + "-" +
  7637.                     strYear.toString() + " " +
  7638.                     strHour.toString() + ":" +
  7639.                     strMinute.toString() + ":" +
  7640.                     strSecond.toString();
  7641.  
  7642.         return strTimeStamp;
  7643.     };
  7644.  
  7645.     this._init = function() {
  7646.         var strValidationData = (objValidationData) ?
  7647.             stringFormat(VALIDATION_DATA,
  7648.                             objValidationData.search, 
  7649.                             objValidationData.toolbar,
  7650.                             objValidationData.isFirst.toString().toUpperCase(), 
  7651.                             objValidationData.isUsageEnabled.toString().toUpperCase()) : "";
  7652.         
  7653.         var strPostParam = stringFormat(LOGIN_RQ, originalCTID, userID, version, os, this.generateTimeStamp(), platform, browserVersion, actingCTID, strValidationData);
  7654.         this.postParams = POST_PARAM + encodeURIComponent(strPostParam);
  7655.     };
  7656.  
  7657.     this._init();
  7658. };
  7659.  
  7660. function LoginRS(xmlLogin) {
  7661.     this.userId = "";
  7662.     this.loginCache = 0;
  7663.     this.xmlAboutBox = null;
  7664.     this.groupingInterval = 0;
  7665.     this.groupingServerUrl = "";
  7666.     this.privacyUrl = "";
  7667.     this.trusteUrl = "";
  7668.     this.usageUrl = "";
  7669.     this.xmlClientLog = null;
  7670.     this.xmlUninstallLog = null;
  7671.     this.xmlLP = null;
  7672.     this.LPServiceUrl = "";
  7673.     this.LPIntervalMM = 0;
  7674.     this.myStuffUrl = "";
  7675.     this.myStuffIntervalMM = 0;
  7676.     this.myStuffSearchUrl = "";
  7677.     this.myStuffEnabled = false;
  7678.     this.myStuffPublisherMinWidth = 0;
  7679.     this.trustedApiDomains = new Array();
  7680.     this.latestVersion = "";
  7681.     this.searchInNewTabServiceUrl = "";
  7682.     this.searchInNewTabIntervalMM = 0;
  7683.     this.searchInNewTabUsageUrl = "";
  7684.     this.searchInNewTabEnabled = false;
  7685.     this.serverDate = "";
  7686.  
  7687.     this.parse = function() {
  7688.         this.userId = XML.GetSingleNodeValue(xmlLogin, "USERID");
  7689.         this.loginCache = XML.GetSingleNodeValueAsInteger(xmlLogin, "LOGIN_CACHE");
  7690.         this.groupingServerUrl = XML.GetSingleNodeValue(xmlLogin, "GROUPING_SERVER_URL");
  7691.         this.serverDate = XML.GetSingleNodeValue(xmlLogin, "SERVER_TIME");
  7692.  
  7693.         //grouping
  7694.         var xmlGrouping = XML.SelectSingleNode(xmlLogin, "GROUPING_INFO");
  7695.         if (xmlGrouping) this.groupingInterval = XML.GetSingleNodeValueAsInteger(xmlGrouping, "INTERVAL");
  7696.  
  7697.         //privacy
  7698.         this.xmlAboutBox = XML.SelectSingleNode(xmlLogin, "ABOUT_BOX");
  7699.         if (this.xmlAboutBox) {
  7700.             this.privacyUrl = XML.GetSingleNodeValue(this.xmlAboutBox, "PRIVACY_PAGE_URL");
  7701.             this.trusteUrl = XML.GetSingleNodeValue(this.xmlAboutBox, "TRUSTE_SEAL_URL");
  7702.         }
  7703.  
  7704.         //usage
  7705.         this.usageUrl = XML.GetSingleNodeValue(xmlLogin, "USERS_USAGE_REQUEST_URL");
  7706.         //client log
  7707.         this.xmlClientLog = XML.SelectSingleNode(xmlLogin, "CLIENT_LOG_SERVICE");
  7708.         //uninstall log
  7709.         this.xmlUninstallLog = XML.SelectSingleNode(xmlLogin, "UNINSTALL_LOG_SERVICE");
  7710.         //language pack
  7711.         this.xmlLP = XML.SelectSingleNode(xmlLogin, "TRANSLATION_SERVICE");
  7712.         if (this.xmlLP) {
  7713.             this.LPServiceUrl = XML.GetSingleNodeValue(this.xmlLP, "SERVICE_URL");
  7714.             this.LPIntervalMM = XML.GetSingleNodeValueAsInteger(this.xmlLP, "INTERVAL_IN_MM");
  7715.         }
  7716.  
  7717.         var xmlMyStuff = XML.SelectSingleNode(xmlLogin, "MY_STUFF");
  7718.         if (xmlMyStuff) {
  7719.             this.myStuffSearchUrl = XML.GetSingleNodeValue(xmlMyStuff, "ADD_STUFF_WEB_URL");
  7720.             this.myStuffEnabled = XML.GetSingleNodeValueAsBoolean(xmlMyStuff, "ENABLED", false);
  7721.             this.myStuffPublisherMinWidth = XML.GetSingleNodeValueAsInteger(xmlMyStuff, "PUBLISHER_RESERVED_AREA_PX");
  7722.  
  7723.             var xmlMyStuffService = XML.SelectSingleNode(xmlMyStuff, "MY_STUFF_SERVICE");
  7724.             if (xmlMyStuffService) {
  7725.                 this.myStuffUrl = XML.GetSingleNodeValue(xmlMyStuffService, "SERVICE_URL");
  7726.                 this.myStuffIntervalMM = XML.GetSingleNodeValueAsInteger(xmlMyStuffService, "INTERVAL_IN_MM");
  7727.             }
  7728.         }
  7729.  
  7730.         var xmlToolbarApi = XML.SelectSingleNode(xmlLogin, "TOOLBAR_API");
  7731.         if (xmlToolbarApi) {
  7732.             var xmlTrustedDomains = XML.SelectSingleNode(xmlToolbarApi, "TRUSTED_DOMAINS");
  7733.             if (xmlTrustedDomains) {
  7734.                 var xmlDomain = null;
  7735.                 for (var i = 0; i < xmlTrustedDomains.childNodes.length; i++) {
  7736.                     xmlDomain = xmlTrustedDomains.childNodes[i];
  7737.                     if (xmlDomain.tagName == "DOMAIN")
  7738.                         this.trustedApiDomains.push(XML.GetXmlNodeValue(xmlDomain));
  7739.                 }
  7740.             }
  7741.         }
  7742.  
  7743.         xpathResult = xmlLogin.ownerDocument.evaluate("LATEST_VERSION/FF", xmlLogin, null, 2, null);
  7744.         if (xpathResult) this.latestVersion = xpathResult.stringValue;
  7745.  
  7746.         //search in new tab
  7747.         var xmlNewTab = XML.SelectSingleNode(xmlLogin, "SEARCH_IN_TAB_SERVICE");
  7748.         if (xmlNewTab) {
  7749.             this.searchInNewTabServiceUrl = XML.GetSingleNodeValue(xmlNewTab, "SERVICE_URL");
  7750.             this.searchInNewTabIntervalMM = XML.GetSingleNodeValueAsInteger(xmlNewTab, "INTERVAL_IN_MM", 1440);
  7751.             this.searchInNewTabUsageUrl = XML.GetSingleNodeValue(xmlNewTab, "USAGE_URL");
  7752.             this.searchInNewTabEnabled = XML.GetSingleNodeValueAsBoolean(xmlNewTab, "ENABLED", false);
  7753.         }
  7754.     };
  7755.  
  7756.     if (xmlLogin)
  7757.         this.parse();
  7758. };
  7759. function MyStuffConsts()
  7760. {
  7761.     this.responseFlags = new Object();
  7762.     this.responseFlags.NOT_MODIFIED = "NOT_MODIFIED";
  7763.     this.responseFlags.MODIFIED = "MODIFIED";
  7764.     this.responseFlags.ERROR= "SERVER_ERROR";
  7765.     this.responseFlags.DELETED = "DELETED";
  7766.     this.responseFlags.COMPONENT_NOT_FOUND = "COMPONENT_NOT_FOUND";
  7767.     this.responseFlags.EXISTS = "EXISTS"; //not returned from server
  7768.     this.responseFlags.CONNECTION_ERROR = "CONNECTION_ERROR";
  7769.     this.responseFlags.SERVER_UNREACHABLE = "SERVER_UNREACHABLE";
  7770.     this.responseFlags.UNSUPPORTED = "UNSUPPORTED";
  7771.     this.responseFlags.BAD_INPUT = "BAD_INPUT";
  7772.     this.responseFlags.INVALID_XML = "INVALID_XML";
  7773. };
  7774. function MyStuffServiceManager(defaultServiceUrl, oPrefs, callback, callbackThis) {
  7775.     var done = false;
  7776.     var reqCount = 0;
  7777.     var DEFAULT_INTERVAL = 1440; //minutes
  7778.  
  7779.     this.request = function(arrMyStuffData, responseCallback, isFromApi, force) {
  7780.         done = false;
  7781.  
  7782.         var serviceUrl = this._getUrl();
  7783.         var myStuffData = null;
  7784.         var arrReq = new Array();
  7785.         var manager = this;
  7786.         var lastUpdateTime;
  7787.         var self = this;
  7788.         for (var i = 0; i < arrMyStuffData.length; i++) {
  7789.             myStuffData = arrMyStuffData[i];
  7790.             lastUpdateTime = (force) ? "" : myStuffData.lastUpdateTime;
  7791.             if (this._isTimeElapse(lastUpdateTime, myStuffData.lastCheckTime)) {
  7792.                 var state = new Object();
  7793.                 state.isFromApi = isFromApi;
  7794.                 state.responseCallback = responseCallback;
  7795.                 state.compGuid = myStuffData.compGuid;
  7796.  
  7797.                 arrReq.push(new MyStuffRQ(serviceUrl, myStuffData.compInstanceGuid, lastUpdateTime,
  7798.                             function(strXml, o, state) { self.response(strXml, o, state); },
  7799.                             state));
  7800.                 reqCount++;
  7801.             }
  7802.         }
  7803.  
  7804.         for (var i = 0; i < arrReq.length; i++)
  7805.             EBServerDataURL.ServiceRequest(arrReq[i]);
  7806.     };
  7807.  
  7808.     this.shutdown = function() {
  7809.         
  7810.     };
  7811.  
  7812.     this.response = function(strXml, o, state) {
  7813.         reqCount--;
  7814.         var compGuid = state.compGuid;
  7815.         if (reqCount == 0) done = true;
  7816.         var myStuffRS = null;
  7817.         var isNetworkError = (o.value == "EB_NETWORK_ERROR");
  7818.         if (!isNetworkError) {
  7819.             var xmlDoc = XML.GetXmlDocument(strXml);
  7820.             if (xmlDoc)
  7821.                 xmlDoc = xmlDoc.documentElement;
  7822.  
  7823.             var myStuffRS = new MyStuffRS(xmlDoc);
  7824.         }
  7825.  
  7826.         callback.call(callbackThis, myStuffRS, compGuid, done, state.responseCallback, state.isFromApi, isNetworkError);
  7827.     };
  7828.     
  7829.     this._getUrl = function() {
  7830.         var strUrl = oPrefs.GetPref(LoginPrefConsts.MyStuffServiceUrl);
  7831.         if (!strUrl) strUrl = defaultServiceUrl;
  7832.  
  7833.         return strUrl;
  7834.     };
  7835.  
  7836.     this._isTimeElapse = function(lastUpdateTime, lastCheckTime) {
  7837.         if (!lastCheckTime || !lastUpdateTime) return true;
  7838.  
  7839.         var iIntervalMM = oPrefs.GetPref(LoginPrefConsts.MyStuffServiceIntervalMM);
  7840.         if (!iIntervalMM) iIntervalMM = DEFAULT_INTERVAL;
  7841.  
  7842.         return lastCheckTime + iIntervalMM * 60 * 1000 <= lastCheckTime;
  7843.     };
  7844. };
  7845. function MyStuffRQ(serviceUrl, componentInstanceGuid, lastUpdateTime, objCallback, state) {
  7846.     var INSTANCE_GUID_ALIAS = "EB_MY_STUFF_INSTANCE_GUID";
  7847.     var LUT_ALIAS = "EB_MY_STUFF_LUT";
  7848.     
  7849.     this.callback = objCallback;
  7850.     this.url = "";
  7851.     this.postParams = null;
  7852.     this.state = state;
  7853.  
  7854.     this._init = function() {
  7855.         this.url = serviceUrl.replace(INSTANCE_GUID_ALIAS, componentInstanceGuid).replace(LUT_ALIAS, lastUpdateTime);
  7856.     };
  7857.  
  7858.     this._init();
  7859. };
  7860. function MyStuffRS(xmlResponse) {
  7861.     this.flags = ToolbarDataParsingXPCOM.myStuff.responseFlags.CONNECTION_ERROR;
  7862.     this.compInstanceGuid = "";
  7863.     this.lastUpdateTime = "";
  7864.     this.xmlComponent = null;
  7865.  
  7866.     this.parse = function() {
  7867.         this.flags = XML.GetSingleNodeValue(xmlResponse, "FLAGS");
  7868.         if (this.flags != ToolbarDataParsingXPCOM.myStuff.responseFlags.MODIFIED) return;
  7869.  
  7870.         this.lastUpdateTime = XML.GetSingleNodeValue(xmlResponse, "LAST_UPDATE_TIME");
  7871.         this.compInstanceGuid = XML.GetSingleNodeValue(xmlResponse, "COMPONENT_INSTANCE_GUID");
  7872.         this.xmlComponent = XML.SelectSingleNode(xmlResponse, "COMPONENT_XML");
  7873.         if (this.xmlComponent)
  7874.             this.xmlComponent = this.xmlComponent.firstChild;
  7875.     };
  7876.  
  7877.     if(xmlResponse)
  7878.         this.parse();
  7879. };
  7880. var ServerMessagesFunctions =
  7881. {
  7882.     getMessageXML: function(strXml) {
  7883.         if (!strXml) return null;
  7884.  
  7885.         try {
  7886.             strXml = XML.LegalizeEBXML(strXml);
  7887.             var xmlDoc = XML.GetXmlDocument(strXml);
  7888.             var xmlRoot = xmlDoc.documentElement;
  7889.             var xmlElem = XML.SelectSingleNode(xmlRoot, "EBMSG");
  7890.             return xmlElem;
  7891.         }
  7892.         catch (ex) {
  7893.             return null;
  7894.         }
  7895.     }
  7896. };
  7897. var SettingsPrefConsts =
  7898. {
  7899.     SettingsLastUpdateTime: "SettingsLastUpdate",
  7900.     SettingsVisualLastUpdateTime: "VusualLastUpdateTime",
  7901.     ServerURL: 'Server',
  7902.     SettingsLastCheckTime: "SettingsLastCheckTime",
  7903.     SettingsCheckIntervalMM: "SettingsCheckIntervalMin",
  7904.     ToolbarLocale: "Locale",
  7905.     DialogsAlignMode: "DialogsAlignMode",
  7906.     IsMulticommunity: 'IsMulticommunity',
  7907.     IsGrouping: 'IsGrouping',
  7908.     CommunityChanged: 'CommunityChanged',
  7909.     MCDetectTooltipWidth: 'MCDetectTooltipWidth',
  7910.     MCDetectTooltipHeight: 'MCDetectTooltipHeight',
  7911.     MCDetectTooltipUrl: 'MCDetectTooltipUrl',
  7912.     CTID: "CTID",
  7913.     MyStuffEnabled: "MyStuffEnabled"
  7914. };
  7915. function SettingsManager(defaultServiceUrl, version, originalCTID, actingCTID, oPrefs, callback, callbackThis) {
  7916.     var SERVER_POST_FIX = "/iis2ebs.asp";
  7917.  
  7918.     this.request = function(bForce, bInvalidateCache) {
  7919.         var lastUpdateTime = oPrefs.GetPref(SettingsPrefConsts.SettingsLastUpdateTime, true);
  7920.         var bIsTimeElapsed = this._isTimeElapse();
  7921.         if (!bIsTimeElapsed && !bForce && lastUpdateTime) return;
  7922.  
  7923.         if (!lastUpdateTime || bForce) lastUpdateTime = 0;
  7924.         //update last check time to now
  7925.         oPrefs.SetPref(SettingsPrefConsts.SettingsLastCheckTime, Date(), true);
  7926.  
  7927.         //request settings
  7928.         var self = this;
  7929.         var oRequest = new SettingsRQ(this._getUrl(), version, originalCTID, actingCTID, lastUpdateTime, bInvalidateCache,
  7930.         function(strSettings) { self.onResponse(strSettings); });
  7931.         EBServerDataURL.ServiceRequest(oRequest);
  7932.     };
  7933.  
  7934.     this.shutdown = function() {
  7935.         //insert self clean up logic here
  7936.     };
  7937.  
  7938.     this._getUrl = function() {
  7939.         var strUrl = oPrefs.GetPref(SettingsPrefConsts.ServerURL, true);
  7940.         if (!strUrl) strUrl = defaultServiceUrl;
  7941.  
  7942.         return strUrl + SERVER_POST_FIX;
  7943.     };
  7944.  
  7945.     this._isTimeElapse = function() {
  7946.         //no last check time
  7947.         var strLastCheckTime = oPrefs.GetPref(SettingsPrefConsts.SettingsLastCheckTime, true);
  7948.         if (!strLastCheckTime) return true;
  7949.  
  7950.         //no interval
  7951.         var iCheckInterval = oPrefs.GetPref(SettingsPrefConsts.SettingsCheckIntervalMM, true);
  7952.         if (!iCheckInterval) return true;
  7953.  
  7954.         iCheckInterval = parseInt(iCheckInterval);
  7955.         var iLastCheckTime = Date.parse(strLastCheckTime);
  7956.         var iNow = Date.parse(Date());
  7957.  
  7958.         //time to check
  7959.         if (iLastCheckTime + iCheckInterval * 60 * 1000 <= iNow)
  7960.             return true;
  7961.  
  7962.         return false;
  7963.     };
  7964.  
  7965.     this.onResponse = function(strSettings) {
  7966.         var xmlElem = ServerMessagesFunctions.getMessageXML(strSettings);
  7967.         if (!xmlElem) return;
  7968.         var settingsRS = new SettingsRS(xmlElem);
  7969.         this.saveSettings(settingsRS);
  7970.     };
  7971.  
  7972.     this.saveSettings = function(settingsRS) {
  7973.         var bLocaleChanged = false;
  7974.  
  7975.         //settings reload interval minutes (cache time)
  7976.         oPrefs.SetPref(SettingsPrefConsts.SettingsCheckIntervalMM, settingsRS.reloadInterval, true);
  7977.         //server last update time
  7978.         oPrefs.SetPref(SettingsPrefConsts.SettingsLastUpdateTime, settingsRS.lastUpdateTime, true);
  7979.         //settings visual last update time for * in MC menu - only for MC/Grouping toolbar
  7980.         if (settingsRS.SettingsVisualLastUpdateTime) {
  7981.             oPrefs.SetPref(SettingsPrefConsts.SettingsVisualLastUpdateTime, settingsRS.visualLastUpdateTime, true);
  7982.             oPrefs.SetPref(SettingsPrefConsts.CommunityChanged, false, true);
  7983.         }
  7984.  
  7985.         //locale
  7986.         var oldLocale = oPrefs.GetPref(SettingsPrefConsts.ToolbarLocale, true);
  7987.         if (oldLocale != settingsRS.toolbarLocale) bLocaleChanged = true;
  7988.         oPrefs.SetPref(SettingsPrefConsts.ToolbarLocale, settingsRS.toolbarLocale, true);
  7989.  
  7990.         //dialogs dir
  7991.         oPrefs.SetPref(SettingsPrefConsts.DialogsAlignMode, (settingsRS.isLocaleRTL) ? "RTL" : "LTR", true);
  7992.  
  7993.         //multicommunity
  7994.         if (settingsRS.isMC)
  7995.             oPrefs.SetPref(SettingsPrefConsts.IsMulticommunity, settingsRS.isMC, false);
  7996.  
  7997.         //grouping
  7998.         oPrefs.SetPref(SettingsPrefConsts.IsGrouping, settingsRS.isGrouping, false);
  7999.  
  8000.         //mc tooltip
  8001.         oPrefs.SetPref(SettingsPrefConsts.MCDetectTooltipWidth, settingsRS.communityDetectedTooltipWidth, false);
  8002.         oPrefs.SetPref(SettingsPrefConsts.MCDetectTooltipHeight, settingsRS.communityDetectedTooltipHeight, false);
  8003.         oPrefs.SetPref(SettingsPrefConsts.MCDetectTooltipUrl, settingsRS.communityDetectedTooltipUrl, false);
  8004.  
  8005.         //alert
  8006.         var oldAlertChannelId = oPrefs.GetPref(AlertPrefConsts.alertChannelId);
  8007.         var bAlertChanged = false;
  8008.         if (!settingsRS.isMC && !settingsRS.isGrouping && settingsRS.alertChannelId) {
  8009.             oPrefs.SetPref(AlertPrefConsts.alertChannelId, settingsRS.alertChannelId);
  8010.             bAlertChanged = oldAlertChannelId != settingsRS.alertChannelId;
  8011.         }
  8012.  
  8013.         if (bLocaleChanged || settingsRS.isSettingsModified || bAlertChanged)
  8014.             callback.call(callbackThis, settingsRS.isSettingsModified, settingsRS.xmlSettings, bLocaleChanged, bAlertChanged);
  8015.     };
  8016. };
  8017. function SettingsRQ(serviceUrl, version, originalCTID, actingCTID, lastUpdateTime, bInvalidateCache, objCallback) {
  8018.     var SETTINGS_RQ = "<EBXML><EBMSGID>CT_MULTI_SETTINGS_RQ</EBMSGID><EBMSG><VERSION>{0}</VERSION><ORIGINAL_CT><CT_ID>{1}</CT_ID></ORIGINAL_CT><ACTING_CT><CT_ID>{2}</CT_ID><LAST_UPDATE_TIME>{3}</LAST_UPDATE_TIME></ACTING_CT>{4}</EBMSG></EBXML>";
  8019.     var INVALIDATE_CACHE = "<INVALIDATE_CACHE>TRUE</INVALIDATE_CACHE>";
  8020.     var POST_PARAM = "RequestString=";
  8021.  
  8022.     this.callback = objCallback;
  8023.     this.url = serviceUrl;
  8024.     this.postParams = "";
  8025.  
  8026.     this._init = function() {
  8027.         var strInvalidateCache = (bInvalidateCache) ? INVALIDATE_CACHE : "";
  8028.         var strPostParam = stringFormat(SETTINGS_RQ, version, originalCTID, actingCTID, lastUpdateTime, strInvalidateCache);
  8029.         this.postParams = POST_PARAM + encodeURIComponent(strPostParam);
  8030.     };
  8031.  
  8032.     this._init();
  8033. };
  8034. function SettingsRS(xmlSettings) {
  8035.     this.originalCTID = "";
  8036.     this.isMC = false;
  8037.     this.isGrouping = false;
  8038.     this.alertChannelId = null;
  8039.     this.actingCTID = "";
  8040.     this.lastUpdateTime = "";
  8041.     this.visualLastUpdateTime = "";
  8042.     this.toolbarLocale = "";
  8043.     this.isLocaleRTL = false;
  8044.     this.xmlSettings = null;
  8045.     this.reloadInterval = 0;
  8046.     this.isSettingsModified = true;
  8047.     
  8048.     // community detected dialog settings
  8049.     this.communityDetectedTooltipWidth = 0;
  8050.     this.communityDetectedTooltipHeight = 0;
  8051.     this.communityDetectedTooltipUrl = 0;
  8052.  
  8053.     this.parse = function() {
  8054.         //Original CTID
  8055.         var xmlOriginalCTID = XML.SelectSingleNode(xmlSettings, "ORIGINAL_CT");
  8056.         if (xmlOriginalCTID) {
  8057.             this.originalCTID = XML.GetSingleNodeValue(xmlOriginalCTID, "CT_ID");
  8058.  
  8059.             //Grouping info
  8060.             var xmlGroupingInfo = XML.SelectSingleNode(xmlOriginalCTID, "GROUPING_INFO");
  8061.             if (xmlGroupingInfo) {
  8062.                 this.isMC = XML.GetSingleNodeValueAsBoolean(xmlGroupingInfo, "OPEN_GROUP");
  8063.                 this.isGrouping = XML.GetSingleNodeValueAsBoolean(xmlGroupingInfo, "PREDEFINED_GROUP");
  8064.             }
  8065.  
  8066.             //Alert info
  8067.             var xmlAlertInfo = XML.SelectSingleNode(xmlOriginalCTID, "ALERT_INFO");
  8068.             if (xmlAlertInfo)
  8069.                 this.alertChannelId = XML.GetSingleNodeValue(xmlAlertInfo, "ALERT_CHANNEL_ID");
  8070.         }
  8071.  
  8072.         //Acting CTID
  8073.         var xmlActingCTID = XML.SelectSingleNode(xmlSettings, "ACTING_CT");
  8074.         if (xmlActingCTID) {
  8075.             this.actingCTID = XML.GetSingleNodeValue(xmlActingCTID, "CT_ID");
  8076.             this.lastUpdateTime = XML.GetSingleNodeValue(xmlActingCTID, "LAST_UPDATE_TIME");
  8077.             this.visualLastUpdateTime = XML.GetSingleNodeValue(xmlActingCTID, "VISUAL_LAST_UPDATE_TIME");
  8078.             this.toolbarLocale = XML.GetSingleNodeValue(xmlActingCTID, "TOOLBAR_LOCALE");
  8079.             this.isLocaleRTL = XML.GetSingleNodeValueAsBoolean(xmlActingCTID, "LOCALE_RTL");
  8080.             this.xmlSettings = XML.SelectSingleNode(xmlActingCTID, "SETTINGS");
  8081.         }
  8082.         //Reload interval
  8083.         this.reloadInterval = XML.GetSingleNodeValueAsInteger(xmlSettings, "RELOAD_INTERVAL");
  8084.  
  8085.         //Community detected tooltip
  8086.         var xmlTooltip = XML.SelectSingleNode(xmlSettings, "COMMUNITY_DETECTED_TOOLTIP");
  8087.         if (xmlTooltip) {
  8088.             this.communityDetectedTooltipWidth = XML.GetSingleNodeValue(xmlTooltip, "WIDTH");
  8089.             this.communityDetectedTooltipHeight = XML.GetSingleNodeValue(xmlTooltip, "HEIGHT");
  8090.             this.communityDetectedTooltipUrl = XML.GetSingleNodeValue(xmlTooltip, "URL");
  8091.         }
  8092.     };
  8093.  
  8094.     this.checkIfModified = function() {
  8095.         if (this.xmlSettings &&
  8096.             this.xmlSettings.childNodes.length == 1 &&
  8097.             XML.GetXmlNodeValue(this.xmlSettings) == "SETTINGS_NOT_MODIFIED")
  8098.         
  8099.         this.isSettingsModified = false;
  8100.     };
  8101.  
  8102.     this.parse();
  8103.     this.checkIfModified();
  8104. };
  8105. var ThirdPartyPrefConsts =
  8106. {
  8107.     ThirdPartyComponentsLastCheck: "ThirdPartyComponentsLastCheck",
  8108.     ThirdPartyComponentsLastUpdate: "ThirdPartyComponentsLastUpdate",
  8109.     ThirdPartyComponentsInterval: "ThirdPartyComponentsInterval"
  8110. };
  8111. function ThirdPartyManager(defaultServiceUrl, originalCTID, actingCTID, oPrefs, callback, callbackThis) {
  8112.     var timeout = null;
  8113.     var SERVER_POST_FIX = "/iis2ebs.asp";
  8114.     var DEFAULT_CHECK_INTERVAL_MM = 24;
  8115.  
  8116.     this.init = function() {
  8117.         var iIntervalMS = this._getNextCheckInterval();
  8118.         var self = this;
  8119.         setTimeout(function() { self.request(); }, iIntervalMS);
  8120.     };
  8121.  
  8122.     this.shutdown = function() {
  8123.         clearTimeout(timeout);
  8124.     };
  8125.  
  8126.     this.reInit = function() {
  8127.         this.shutdown();
  8128.         this.init();
  8129.     };
  8130.  
  8131.     this.request = function(bForce) {
  8132.         var lastUpdateTime = oPrefs.GetPref(ThirdPartyPrefConsts.ThirdPartyComponentsLastUpdate, true);
  8133.         var bIsTimeElased = (this._getNextCheckInterval() == 0) ? true : false;
  8134.  
  8135.         if (!bIsTimeElased && !bForce && lastUpdateTime) return;
  8136.  
  8137.         if (!lastUpdateTime || bForce) lastUpdateTime = 0;
  8138.  
  8139.         //update last check time to now
  8140.         oPrefs.SetPref(ThirdPartyPrefConsts.ThirdPartyComponentsLastCheck, Date(), true);
  8141.  
  8142.         var platform = AppInfo.xulRuntime.name.toUpperCase();
  8143.         //request 3rd party
  8144.         var self = this;
  8145.         var oRequest = new ThirdPartyRQ(this._getUrl(), actingCTID, platform, lastUpdateTime,
  8146.                             function(strThirdParty) { self.onResponse(strThirdParty); });
  8147.         EBServerDataURL.ServiceRequest(oRequest);
  8148.         this.reInit();
  8149.     };
  8150.  
  8151.     this.onResponse = function(strThirdParty) {
  8152.         var xmlElem = ServerMessagesFunctions.getMessageXML(strThirdParty);
  8153.         var thirdPartyRS = new ThirdPartyRS(xmlElem);
  8154.         this.saveThirdParty(thirdPartyRS);
  8155.     };
  8156.  
  8157.     this.saveThirdParty = function(thirdPartyRS) {
  8158.         if (thirdPartyRS.lastUpdateTime)
  8159.             oPrefs.SetPref(ThirdPartyPrefConsts.ThirdPartyComponentsLastUpdate, thirdPartyRS.lastUpdateTime, true);
  8160.  
  8161.         if (thirdPartyRS.reloadInterval && isFinite(thirdPartyRS.reloadInterval)) {
  8162.             //patch, older version wrote this value as string
  8163.             if (oPrefs.HasUserValue(ThirdPartyPrefConsts.ThirdPartyComponentsInterval, false))
  8164.                 oPrefs.Clear(ThirdPartyPrefConsts.ThirdPartyComponentsInterval, false);
  8165.             oPrefs.SetPref(ThirdPartyPrefConsts.ThirdPartyComponentsInterval, thirdPartyRS.reloadInterval, false);
  8166.         }
  8167.  
  8168.         //modify new xmlThirdParty received.
  8169.         if (thirdPartyRS.isModifed && thirdPartyRS.xmlThirdPartyComponents)
  8170.             callback.call(callbackThis, thirdPartyRS.xmlThirdPartyComponents);
  8171.     };
  8172.  
  8173.     this._getUrl = function() {
  8174.         var strUrl = oPrefs.GetPref(SettingsPrefConsts.ServerURL, false);
  8175.         if (!strUrl) strUrl = defaultServiceUrl;
  8176.  
  8177.         return strUrl + SERVER_POST_FIX;
  8178.     };
  8179.  
  8180.     this._getNextCheckInterval = function() {
  8181.         //no last check time
  8182.         var strLastCheckTime = oPrefs.GetPref(ThirdPartyPrefConsts.ThirdPartyComponentsLastCheck, true);
  8183.         if (!strLastCheckTime) return 0;
  8184.  
  8185.         //no interval
  8186.         var iCheckInterval = oPrefs.GetPref(ThirdPartyPrefConsts.ThirdPartyComponentsInterval, false);
  8187.         if (!iCheckInterval)
  8188.             iCheckInterval = DEFAULT_CHECK_INTERVAL_MM;
  8189.         iCheckInterval *= 60 * 60 * 1000;
  8190.  
  8191.         var iLastCheckTime = Date.parse(strLastCheckTime);
  8192.         var iNow = Date.parse(Date());
  8193.  
  8194.         //time to check
  8195.         var iNextCheck = iLastCheckTime + iCheckInterval - iNow;
  8196.         if (iNextCheck < 0) iNextCheck = 0;
  8197.  
  8198.         return iNextCheck
  8199.     };
  8200. };
  8201. function ThirdPartyRQ(serviceUrl, actingCTID, platform, lut, callback) {
  8202.     var THIRD_PARTY_RQ = "<EBXML><EBMSGID>CT_THIRD_PARTY_COMPONENTS_RQ</EBMSGID><EBMSG><CT_ID>{0}</CT_ID><PLATFORM>{1}</PLATFORM><LAST_UPDATE_TIME>{2}</LAST_UPDATE_TIME></EBMSG></EBXML>";
  8203.     var POST_PARAM = "RequestString=";
  8204.     this.callback = callback;
  8205.     this.url = serviceUrl;
  8206.     this.postParams = "";
  8207.  
  8208.     this._init = function() {
  8209.     var strPostParam = stringFormat(THIRD_PARTY_RQ, actingCTID, platform, lut);
  8210.         this.postParams = POST_PARAM + encodeURIComponent(strPostParam);
  8211.     };
  8212.  
  8213.     this._init(); 
  8214. };
  8215. function ThirdPartyRS(xmlThirdParty) {
  8216.     this.xmlThirdPartyComponents = null;
  8217.     this.lastUpdateTime = "";
  8218.     this.reloadInterval = 0;
  8219.     this.isModifed = true;
  8220.  
  8221.     this.parse = function() {
  8222.         this.xmlThirdPartyComponents = XML.SelectSingleNode(xmlThirdParty, "THIRD_PARTY_COMPONENTS");
  8223.         this.lastUpdateTime = XML.GetSingleNodeValue(xmlThirdParty, "LAST_UPDATE_TIME");
  8224.         this.reloadInterval = XML.GetSingleNodeValueAsInteger(xmlThirdParty, "RELOAD_INTERVAL");
  8225.     };
  8226.  
  8227.     this.checkIfModified = function() {
  8228.         if (this.xmlThirdPartyComponents &&
  8229.             this.xmlThirdPartyComponents.childNodes.length == 1 &&
  8230.             XML.GetXmlNodeValue(this.xmlThirdPartyComponents) == "NOT_MODIFIED")
  8231.             this.isModifed = false;
  8232.     };
  8233.  
  8234.     if (xmlThirdParty) {
  8235.         this.parse();
  8236.         this.checkIfModified();
  8237.     }
  8238. };
  8239. var UninstallLogConsts =
  8240. {
  8241.     defaultServiceUrl: "http://uninstall.users.conduit.com/Uninstall.asmx/RegisterToolbarUninstallation"
  8242. };
  8243. var UninstallLogPrefConsts =
  8244. {
  8245.     serviceUrl: "uninstallLogServiceUrl"
  8246. }
  8247.  
  8248. function UninstallLogDS(version, originalCTID, actingCTID, os, browser, uid) {
  8249.     this.version = version;
  8250.     this.originalCTID = originalCTID;
  8251.     this.platform = "FF";
  8252.     this.os = os;
  8253.     this.browser = XML.ToLegalXML(browser);
  8254.     this.ctid = actingCTID;
  8255.     this.uid = uid;
  8256. };
  8257. function UninstallLogManager() {
  8258.     //this hash is used to track that only one window will send a message
  8259.     var sentHash = new HashArray();
  8260.  
  8261.     this.onLoginResponse = function(xmlUninstallLog, strOriginalCTID) {
  8262.         if (!xmlUninstallLog) return;
  8263.  
  8264.         var strSerivceUrl = XML.GetSingleNodeValue(xmlUninstallLog, "SERVICE_URL");
  8265.         this._updateServiceUrl(strOriginalCTID, strSerivceUrl);
  8266.     };
  8267.  
  8268.     this.send = function(objUninstallLogDS) {
  8269.         if (sentHash.Contains(objUninstallLogDS.originalCTID)) return;
  8270.  
  8271.         sentHash.Add(objUninstallLogDS.originalCTID, true);
  8272.         var strServiceUrl = this._getServiceUrl(objUninstallLogDS.originalCTID);
  8273.         var objMessage = new UninstallLogRQ(strServiceUrl, objUninstallLogDS);
  8274.         EBServerDataURL.ServiceRequest(objMessage);
  8275.     };
  8276.  
  8277.     this._updateServiceUrl = function(strCTID, strServiceUrl) {
  8278.         var strPrefName = strCTID + "." + UninstallLogPrefConsts.serviceUrl;
  8279.         PrefService.SetPref(strPrefName, strServiceUrl);
  8280.     };
  8281.  
  8282.     this._getServiceUrl = function(strCTID) {
  8283.         var strPrefName = strCTID + "." + UninstallLogPrefConsts.serviceUrl;
  8284.         if (!PrefService.HasUserValue(strPrefName))
  8285.             return UninstallLogConsts.defaultServiceUrl;
  8286.         else
  8287.             return PrefService.GetPref(strPrefName);
  8288.     };
  8289. };
  8290. function UninstallLogRQ(serviceUrl, objUninstallLogDS) {
  8291.     var UNINSTALL_LOG_RQ = "<USERS_UNINSTALL_REQUEST><TOOLBAR_INFO><TOOLBAR_VERSION>{0}</TOOLBAR_VERSION><CTID>{1}</CTID><PLATFORM>{2}</PLATFORM><BROWSER_VERSION>{3}</BROWSER_VERSION><OPERATING_SYSTEM>{4}</OPERATING_SYSTEM><ACTING_CTID>{5}</ACTING_CTID></TOOLBAR_INFO><UID>{6}</UID></USERS_UNINSTALL_REQUEST>";
  8292.     var POST_PARAM = "RequestString=";
  8293.     this.callback = null;
  8294.     this.url = serviceUrl;
  8295.     this.postParams = "";
  8296.  
  8297.     this._init = function() {
  8298.         var strPostParam = stringFormat(UNINSTALL_LOG_RQ,
  8299.                                         objUninstallLogDS.version,
  8300.                                         objUninstallLogDS.originalCTID,
  8301.                                         objUninstallLogDS.platform,
  8302.                                         objUninstallLogDS.browser,
  8303.                                         objUninstallLogDS.os,
  8304.                                         objUninstallLogDS.ctid,
  8305.                                         objUninstallLogDS.uid);
  8306.         this.postParams = POST_PARAM + encodeURIComponent(strPostParam);
  8307.     };
  8308.  
  8309.     this._init();  
  8310. };
  8311. var UninstallLogXPCOM =
  8312. {
  8313.     uninstallLogDS: UninstallLogDS,
  8314.     manager: new UninstallLogManager()
  8315. };
  8316. var ToolbarDataParsingXPCOM =
  8317. {
  8318.     dataNodeFactory: new DataNodeFactory,
  8319.     dataObjects:
  8320.     {
  8321.         Application: DataNodeApplication,
  8322.         Command: DataNodeCommand,
  8323.         Link: DataNodeLink,
  8324.         PopHtml: DataNodePopHtml,
  8325.         Rss: DataNodeRss
  8326.     },
  8327.     
  8328.     dataNodeTypes: new DataNodeTypes(),
  8329.  
  8330.     ComponentType:
  8331.     {
  8332.         Settings: "Settings",
  8333.         ThirdParty: "ThirdParty",
  8334.         UserAdded: "UserAdded",
  8335.         MyStuff: "MyStuff"
  8336.     },
  8337.  
  8338.     Editable:
  8339.     {
  8340.         FULL: 'FULL',
  8341.         NONE: 'NONE'
  8342.     },
  8343.  
  8344.     ComponentsID:
  8345.     {
  8346.         MainMenu: '100',
  8347.         SearchBox: '101',
  8348.         Highlighter: '102',
  8349.         EMailNotifier: '103',
  8350.         Privacy: '104',
  8351.         Weather: '105',
  8352.         Radio: '107',
  8353.         OldRadio: '108',
  8354.         // 109 - is chat component
  8355.         Facebook: '116',
  8356.         MultiCommunity: '200',
  8357.         MyGadgets: '202',
  8358.         Chevron: "201",
  8359.         ChevronMyStuff: "202",
  8360.         MyStuffSplitter: "203",
  8361.         Chat: '',
  8362.         MyStuffAddButton: "204",
  8363.         MyStuffOptionsButton: "205",
  8364.         MyStuffUsage: "300"
  8365.     },
  8366.     
  8367.     myStuff: new MyStuffConsts(), 
  8368.     
  8369.     toolbarItems:
  8370.     {
  8371.         browserComponent: BrowserItem,
  8372.         button: ButtonItem,
  8373.         chat: ChatItem,
  8374.         dynamicMenu: DynamicMenuItem,
  8375.         emailNotifier: EMailNotifierItem,
  8376.         externalComponent: ExternalComponentItem,
  8377.         feed: FeedItem,
  8378.         highlighter: HighlighterItem,
  8379.         label: LabelItem,
  8380.         multicommunity: MultiCommunityItem,
  8381.         multiFeed: MultiFeedItem,
  8382.         privacy: PrivacyItem,
  8383.         radio: RadioItem,
  8384.         searchBox: SearchBoxItem,
  8385.         separator: SeparatorItem,
  8386.         toggleComponent: ToggleItem,
  8387.         weather: WeatherItem,
  8388.         myStuffWithOptions: MyStuffWithOptionsButtonItem,
  8389.         myStuff: MyStuffButtonItem,
  8390.         twitter: TwitterItem,
  8391.         facebook: FacebookItem
  8392.     },
  8393.  
  8394.     toolbarItemsFactory: new ToolbarItemsFactory(),
  8395.     toolbarItemData: ToolbarItemData,
  8396.  
  8397.     observerData:
  8398.     {
  8399.         settings: "eb-settings",
  8400.         userAddComponents: "eb-userComponents",
  8401.         thirdParty: "eb-thirdParty",
  8402.         languagePack: "eb-languagePack",
  8403.         switchCommunity: "eb-switchCommunity",
  8404.         myStuff: "eb-myStuff",
  8405.         myStuffSwitchedOn: "eb-myStuffSwitchedOn"
  8406.     },
  8407.     
  8408.     observerTopic: "eb-toolbar-data-changed",
  8409.  
  8410.     consts: new ToolbarDataConsts()
  8411. };
  8412. function ToolbarDataConsts() {
  8413.     this.aliases = new Object();
  8414.     this.aliases.MainFrameURL = 'EB_MAIN_FRAME_URL';
  8415.     this.aliases.ToolbarID = 'EB_TOOLBAR_ID';
  8416.     this.aliases.UserID = 'EB_USER_ID';
  8417.     this.aliases.SearchTerm = 'EB_SEARCH_TERM';
  8418.     this.aliases.ToolbarVersion = 'EB_TOOLBAR_VERSION';
  8419.     this.aliases.ToolbarOriginalID = 'EB_ORIGINAL_CTID';
  8420.     this.aliases.MainFrameTitle = 'EB_MAIN_FRAME_TITLE';
  8421.     this.aliases.ToolbarSubDomain = 'EB_TOOLBAR_SUB_DOMAIN';
  8422. };
  8423. var LanguagePackDefaults =
  8424. {
  8425.     terms: new HashArray(true),
  8426.  
  8427.     init: function() {
  8428.         this.terms.Add('CTLP_STR_ID_GLOBAL_OK', 'OK');
  8429.         this.terms.Add('CTLP_STR_ID_GLOBAL_CANCEL', 'Cancel');
  8430.         this.terms.Add('CTLP_STR_ID_GLOBAL_YES', 'Yes');
  8431.         this.terms.Add('CTLP_STR_ID_GLOBAL_NO', 'No');
  8432.         this.terms.Add('CTLP_STR_ID_GLOBAL_BROWSE', 'Browse...');
  8433.         this.terms.Add('CTLP_STR_ID_GLOBAL_NEW', 'new');
  8434.         this.terms.Add('CTLP_STR_ID_GLOBAL_UNREAD', 'unread');
  8435.         this.terms.Add('CTLP_ADD_USER_COMPONENT_WARNING_DESCRIPTION', 'You are about to add a component to your toolbar. Click OK to allow this component.');
  8436.         this.terms.Add('CTLP_STR_ID_ADD_ALERT_DESCRIPTION', 'You are about to subscribe to receive new alerts.\n\nAlerts are special messages that are sent to you via the community toolbar.\nThe alerts usually include important news or special offers, are sent only to members of the community, and can always be easily unsubscribed.\n\nDo you want to subscribe to the alerts?');
  8437.         this.terms.Add('CTLP_STR_ID_GLOBAL_DO_NOT_SHOW_AGAIN', 'Do not show again');
  8438.         this.terms.Add('CTLP_STR_ID_GLOBAL_HELP', 'Help');
  8439.  
  8440.         this.terms.Add('CTLP_STR_ID_SEPERATOR_TEXT', 'Separator');
  8441.         this.terms.Add('CTLP_STR_ID_SEARCH_HISTORY', 'History');
  8442.         this.terms.Add('CTLP_STR_ID_SEARCH_SUGGESTIONS', 'Suggestions');
  8443.  
  8444.         this.terms.Add('CTLP_STR_ID_NO_SEARCH_HISTORY_FOUND', '(No Search History)');
  8445.         this.terms.Add('\@APPSERVER_MAIN_MENU_PRIVACY_APPSERVER\@', 'Privacy');
  8446.  
  8447.         this.terms.Add('CTLP_STR_ID_GLOBAL_EULA', 'End user License Agreement');
  8448.         this.terms.Add('CTLP_STR_ID_GLOBAL_PRIVACY_POLICY', 'Privacy Policy');
  8449.         //this.terms.Add('CTLP_STR_ID_GLOBAL_PRIVACY_TEXT', 'For more information about the community toolbar, please view our');
  8450.         this.terms.Add('CTLP_STR_ID_GLOBAL_AND', 'and');
  8451.         this.terms.Add('CTLP_STR_ID_GLOBAL_LEARN_MORE', 'Learn more...');
  8452.         this.terms.Add('CTLP_STR_ID_SEARCH_LIST_BOX_HISTORY_TITLE', 'Clear History');
  8453.  
  8454.         //toolbar options dialog
  8455.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_TITLE', 'Toolbar Options');
  8456.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_PERSONAL_COMPONENTS_TAB_TITLE', 'Personal Components');
  8457.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_PERSONAL_COMPONENTS_TAB_DESCRIPTION', 'You can choose to include these additional useful components in the toolbar:');
  8458.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_EMAIL_NOTIFIER_COMP_TITLE', 'E-mail Notifier');
  8459.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_EMAIL_NOTIFIER_COMP_DESCRIPTION', 'Automatically notifies you of new e-mails you receive');
  8460.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_EMAIL_NOTIFIER_SETTINGS_BUTTON', 'E-mail Notifier Settings…');
  8461.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_PRIVACY_COMP_TITLE', 'Privacy Component');
  8462.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_PRIVACY_COMP_DESCRIPTION', 'Includes cookie cleaner, history cleaner, and cache cleaner.');
  8463.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_WEATHER_COMP_TITLE', 'Weather Forecaster');
  8464.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_WEATHER_COMP_DESCRIPTION', 'Shows the current local weather all over the world');
  8465.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_RADIO_COMP_TITLE', 'Online Radio Player');
  8466.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_RADIO_COMP_DESCRIPTION', 'Lets you easily listen to online radio stations and podcasts');
  8467.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_PREDEFINED_COMPONENTS_TAB_TITLE', 'Predefined Components');
  8468.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_PREDEFINED_COMPONENTS_TAB_DESCRIPTION', 'You can select which one of these predefined components to add and remove from the toolbar.');
  8469.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_DELETE_COMPONENT_BUTTON', 'Delete');
  8470.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_USEFUL_COMPONENTS_TAB_TITLE', 'Useful Components');
  8471.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_USEFUL_COMPONENTS_TAB_DESCRIPTION', 'You can choose to include these additional useful components in the toolbar.');
  8472.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_AUTO_UPDATE_DESCRIPTION', 'Enable Automatic Update');
  8473.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_TAB_TITLE', 'Additional Settings');
  8474.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_TAB_DESCRIPTION', 'You will be able to change this settings at any time.');
  8475.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_ENABLE_HISTORY', 'Enable search box history');
  8476.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_SUGGEST', 'Suggest search from my search history');
  8477.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_BUTTON_CLEAR_HISTORY', 'Clear search history');
  8478.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_CONFIRM_CLEAR_HISTORY', 'Are you sure you want to clear the search history?');
  8479.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_USAGE', 'Send usage statistics (help us improve our toolbar).');
  8480.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_CLICK_TO_SEARCHBOX', 'Enable select to search box (selecting text on the page will send it to the search box).');
  8481.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_BACK_TO_DEFAULT_SEARCH_ENGINE', 'Always revert to default search engine.');
  8482.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_SEARCH_IN_NEW_TAB', 'Show the Search page when opening a new tab.');
  8483.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_HIDE_COMPONENT_BUTTON', 'Hide');
  8484.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_SHOW_COMPONENT_BUTTON', 'Show');
  8485.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ADDITIONAL_SHOW_POPUP_ON_COMMUNITY_DETECTED', 'Show tooltip when community toolbar detected.');
  8486.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ALERT_SETTINGS_BUTTON', 'Alert Settings...');
  8487.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ALERT_SETTINGS_DESCRIPTION', 'Alerts are community messages you can get right to your desktop.');
  8488.         this.terms.Add('CTLP_STR_ID_FIX_PAGE_NOT_FOUND_ERRORS', 'Fix "page not found" errors.');
  8489.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_ENABLE_SEARCH_ADDRESS_BAR', 'Enable search from address bar.');
  8490.         //my stuff in options dialog
  8491.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_MY_STUFF_TAB_TITLE', 'My Stuff');
  8492.         this.terms.Add('CTLP_STR_ID_OPTIONS_DLG_MY_STUFF_TAB_DESCRIPTION', 'The components you added to your toolbar are listed below.\nSelect a component and then an action button.');
  8493.  
  8494.         //email notifier
  8495.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_TITLE', 'E-mail Notifier Settings');
  8496.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_INNER_TITLE', 'E-mail Notifier Settings');
  8497.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_INNER_DESCRIPTION', 'Get notified of new e-mails in your e-mail accounts directly in the toolbar.');
  8498.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_LIST_TITLE', 'Just enter your e-mail account details and get easy access to all of your e-mails.');
  8499.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_LIST_CUL_NAME', 'Account Name');
  8500.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_LIST_CUL_ADDRESS', 'E-mail Address');
  8501.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_LIST_CUL_TYPE', 'Account Type');
  8502.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_LIST_CUL_AUTOLOGIN', 'Auto Login');
  8503.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_BUTT_ADD_TEXT', 'Add');
  8504.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_BUTT_EDIT_TEXT', 'Edit');
  8505.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_BUTT_DELETE_TEXT', 'Delete');
  8506.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_CHECK_EVERY_TEXT', 'Check for new e-mails every (minutes):');
  8507.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_PLAY_SOUND_TEXT', 'Play a sound when new e-mails arrive');
  8508.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_DEFAULT_SOUND_TEXT', 'Use default sound');
  8509.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_DIFFERENT_SOUND_TEXT', 'Choose a different sound');
  8510.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_BUTT_PLAY_TEXT', 'Play');
  8511.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_FEEDBACK_LINK_TEXT', 'Tell us what you think about this component');
  8512.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_SETTINGS_DLG_BUTT_TBOPTIONS_TEXT', 'Toolbar Options…');
  8513.  
  8514.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_TITLE', 'E-mail Account Details');
  8515.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_INNER_TITLE', 'E-mail Account Details');
  8516.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_TYPE_TEXT', 'Account type:');
  8517.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_HOTMAIL', 'Hotmail');
  8518.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_YAHOO', 'Yahoo');
  8519.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_GAMIL', 'Gmail');
  8520.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_POP3', 'POP3');
  8521.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_SUPPORTED_DOMAINS_TEXT', 'Supported domains');
  8522.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_EMAIL_ADDRESS_TEXT', 'E-mail Address');
  8523.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_USER_NAME_TEXT', 'User Name');
  8524.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_PASSWORD_TEXT', 'Password');
  8525.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_NAME_ACCOUNT_TEXT', 'Name your account');
  8526.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_INCOMMING_SERVER_TEXT', 'Incoming mail server');
  8527.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_PORT_TEXT', 'Port');
  8528.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_OPEN_DEFAULT_CLIENT_TEXT', 'Open default mail client');
  8529.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_AUTO_LOGIN_TEXT', 'Auto Login (will not ask for password when logging into my account)');
  8530.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ADD_DLG_BUTT_TEST_MAIL_TEXT', 'Test e-mail account…');
  8531.  
  8532.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_TITLE', 'E-mail Account Test');
  8533.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_INNER_TITLE', 'E-mail Account Test');
  8534.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_CUL_TASKS', 'Tasks');
  8535.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_CUL_STATUS', 'Status');
  8536.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_ESTABLISH', 'Entablish network connection');
  8537.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_FIND_SERVER', 'Find mail server');
  8538.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_LOGINTO', 'Log into mail server');
  8539.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_FAILED_TESTING', 'Failed testing mail acocunt');
  8540.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_COMPLETED', 'Completed');
  8541.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_DONE_TESTING', 'Done');
  8542.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_FAILED', 'Failed');
  8543.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_PLEASE_LOGOUT_TEXT', 'Please logout of your web accounts first');
  8544.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_TEST_DLG_COMPLETED_SUCC_TEXT', 'Mail account tested successfully');
  8545.  
  8546.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_PASSWORD_DLG_TITLE', 'Confirm your account password');
  8547.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_PASSWORD_DLG_DESC', "To enable automatic login please confirm this account's password");
  8548.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_PASSWORD_DLG_PASSWORD', 'Password:');
  8549.  
  8550.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ALERT_MESSAGE_BOX_TITLE', 'E-mail Notifier Alert');
  8551.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ALERT_MESSAGE_ACCOUNT_ALREADY_EXISTS', 'You have already defined an account with that address');
  8552.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ALERT_MESSAGE_EMAIL_NOT_SUPPORTED', 'This e-mail address domain is not supported…');
  8553.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ALERT_MESSAGE_INCCORECT_ADDRESS', 'The E-mail address you have entered appears to be incorrect');
  8554.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ALERT_MSG_WRONG_PASSWORD_TITLE', 'Check e-mail password');
  8555.         this.terms.Add('CTLP_STR_ID_EMAIL_NOTIFIER_ALERT_MSG_WRONG_PASSWORD', 'Incorrect password! Please enter the password that you have defined in this account');
  8556.  
  8557.         // Radio
  8558.         this.terms.Add('CTLP_STR_ID_RADIO_SEARCH_DLG_TITLE', 'Search results for');
  8559.         this.terms.Add('CTLP_STR_ID_RADIO_SEARCH_DLG_HEADER', 'Select the stations you want to add and click OK');
  8560.         this.terms.Add('CTLP_STR_ID_RADIO_SEARCH_DLG_NO_STATIONS_FOUND', 'No stations were found');
  8561.  
  8562.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_ADD_AND_EDIT', 'Add and Edit Stations');
  8563.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_USER_DEFINED_STATIONS_TITLE', 'My Stations');
  8564.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_USER_DEFINED_STATIONS_TITLE_TTIP', 'Stations that you defined');
  8565.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_PUBLISHER_MORE_STATIONS_TITLE', 'More');
  8566.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_PUBLISHER_MORE_STATIONS_TITLE_TTIP', 'View additional radio stations');
  8567.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_NOPODCAST_TITLE', 'No items found in podcast');
  8568.         this.terms.Add('CTLP_STR_ID_RADIO_MENU_PODCAST_TIMEOUT_TITLE', 'Podcast currently not available');
  8569.         this.terms.Add('CTLP_STR_ID_RADIO_LOCAL_STATIONS', 'Local Stations');
  8570.         this.terms.Add('CTLP_STR_ID_RADIO_RECENT_STATIONS', 'Recent Stations');
  8571.  
  8572.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_COMBO_CHOOSE_STREAM_TYPE', 'Chose stream type');
  8573.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_COMBO_CHOOSE_WINDOWS_MEDIA_PLAYER', 'Windows Media Player');
  8574.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_COMBO_CHOOSE_REAL_PLAYER', 'Real Player');
  8575.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_COMBO_CHOOSE_PODCAST', 'Podcast');
  8576.  
  8577.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_CANT_REMOVE_MESSAGE_CURRENT_STATION_PLAYED', "cannot be deleted since it's currently being played. Please switch to a different station and then delete this one");
  8578.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_CANT_REMOVE_MESSAGE_CURRENT_STATION_STOPPED', "cannot be deleted since it's selected for playing. Please switch to a different station and then delete this one");
  8579.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_SELECT_AUDIO_FILES_TITLE', "Select Audio Files");
  8580.  
  8581.         this.terms.Add('CTLP_STR_ID_RADIO_LOADING', 'Loading...');
  8582.         this.terms.Add('CTLP_STR_ID_RADIO_LOADING_TTIP', 'Wait loading...');
  8583.         this.terms.Add('CTLP_STR_ID_RADIO_NO_STATIONS', 'No stations');
  8584.         this.terms.Add('CTLP_STR_ID_RADIO_PLAY_TTIP', 'Play');
  8585.         this.terms.Add('CTLP_STR_ID_RADIO_STOP_TTIP', 'Stop');
  8586.         this.terms.Add('CTLP_STR_ID_RADIO_SHRINK_TTIP', 'Shrink');
  8587.         this.terms.Add('CTLP_STR_ID_RADIO_UNSHRINK_TTIP', 'Unshrink');
  8588.         this.terms.Add('CTLP_STR_ID_RADIO_VOLUME_TTIP', 'Volume');
  8589.         this.terms.Add('CTLP_STR_ID_RADIO_PLAY_EQUALIZER_TTIP', 'Playing');
  8590.         this.terms.Add('CTLP_STR_ID_RADIO_STOP_EQUALIZER_TTIP', 'Stopped');
  8591.         this.terms.Add('CTLP_STR_ID_RADIO_BUFFERING_EQUALIZER_TTIP', 'Buffering');
  8592.         this.terms.Add('CTLP_STR_ID_RADIO_CONNECTING_EQUALIZER_TTIP', 'Connecting...');
  8593.         this.terms.Add('CTLP_STR_ID_RADIO_SETTINGS_DLG_TITLE', 'Radio Stations');
  8594.         this.terms.Add('CTLP_STR_ID_RADIO_SETTINGS_DLG_FIND_MORE_STATIONS', 'Add Stations');
  8595.         this.terms.Add('CTLP_STR_ID_RADIO_SETTINGS_DLG_IDC_STATIC_SEARCH_STATIONS', 'Search for Stations');
  8596.         this.terms.Add('CTLP_STR_ID_RADIO_SETTINGS_DLG_FIND_MORE_STATIONS_TTIP', 'Add and edit the stations in the radio');
  8597.         this.terms.Add('CTLP_STR_ID_RADIO_SETTINGS_DLG_IDC_BUTTON_SEARCH_DIALOG', 'Search');
  8598.  
  8599.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_80S', "80's");
  8600.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_ALTERNATIVE', 'Alternative');
  8601.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_CHRISTIAN', 'Christian');
  8602.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_COUNTRY', 'Country');
  8603.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_LATINE', 'Latin');
  8604.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_OLDIES', 'Oldies');
  8605.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_RAP', 'Rap');
  8606.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_ROCK', 'Rock')
  8607.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_JAZZ', 'Jazz');
  8608.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_DEFINE_YOUR_OWN', 'Define your own station');
  8609.         this.terms.Add('CTLP_STR_ID_RADIO_CATEGORY_BROWSE_LOCAL', 'Add your files');
  8610.  
  8611.         this.terms.Add('CTLP_STR_ID_RADIO_STATIC_MANAGE_MY_STATIONS', 'Manage Your Stations');
  8612.         this.terms.Add('CTLP_STR_ID_RADIO_BUTTON_EDIT_STATION', 'Edit');
  8613.         this.terms.Add('CTLP_STR_ID_RADIO_BUTTON_REMOVE_DIALOG', 'Remove');
  8614.         this.terms.Add('CTLP_STR_RADIO_STATIONS_LIST_NAME_CAPTION', 'Station Name');
  8615.         this.terms.Add('CTLP_STR_RADIO_STATIONS_LIST_URL_CAPTION', 'URL');
  8616.  
  8617.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_ADD_TITLE', 'Add Your Own Radio Station');
  8618.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_EDIT_TITLE', 'Edit Radio Station');
  8619.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_ADD_HEADER', 'Enter the name and stream URL of the station you want to add');
  8620.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_EDIT_HEADER', 'Edit the name and steam URL of the selected station');
  8621.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_INVALID_STREAM_URL', 'Invalid stream URL');
  8622.         this.terms.Add('CTLP_STR_ID_RADIO_ADD_DLG_INVALID_STREAM_CAPTION', 'Invalid Stream Caption');
  8623.         this.terms.Add('CTLP_STR_ID_STATIC_NAME_EG', 'e.g. 100FM');
  8624.         this.terms.Add('CTLP_STR_ID_STATIC_URL_EG', 'e.g. http://radio-station.com/stream.asx');
  8625.         this.terms.Add('CTLP_STR_ID_STATIC_URL', 'Stream URL');
  8626.         this.terms.Add('CTLP_STR_ID_STATIC_NAME', 'Station Name');
  8627.         this.terms.Add('CTLP_STR_ID_STATIC_TYPE', 'Stream Type');
  8628.         this.terms.Add('CTLP_STR_ID_RADIO_REMOVE_MSG', 'Are you sure that you want to delete the selected station/s?');
  8629.         this.terms.Add('CTLP_STR_ID_RADIO_REMOVE_MSG_CAPTION', 'Remove Radio Stations');
  8630.  
  8631.         this.terms.Add('CTLP_STR_ID_RADIO_CLEAR_RECENT_STATIONS_MSG_CAPTION', 'Clear Recent Stations List');
  8632.         this.terms.Add('CTLP_STR_ID_RADIO_CLEAR_RECENT_STATIONS_MSG', 'Are you sure that you want to clear the recent stations list ?');
  8633.         this.terms.Add('CTLP_STR_ID_RADIO_CLEAR_RECENT_LIST', 'Clear Recent Stations List');
  8634.         this.terms.Add('CTLP_STR_ID_RADIO_SETTINGS_TELL_US', 'Tell us what you think about the Radio Player');
  8635.  
  8636.  
  8637.         //RSS
  8638.         this.terms.Add('CTLP_STR_ID_RSS_REFRESH_TOOLTIP', 'Refresh');
  8639.         this.terms.Add('CTLP_STR_ID_RSS_DELETE_ALL_ITEMS_TOOLTIP', 'Delete All Items');
  8640.         this.terms.Add('CTLP_STR_ID_RSS_MARK_ALL_AS_READ_TOOLTIP', 'Mark All Items As Read"');
  8641.         this.terms.Add('CTLP_STR_ID_RSS_MARK_ALL_AS_UNREAD_TOOLTIP', 'Mark All Items As Unread');
  8642.         this.terms.Add('CTLP_STR_ID_RSS_ADD_YOUR_COMMET_TO_BOX', 'Add your own comment to this box');
  8643.         this.terms.Add('CTLP_STR_ID_RSS_OPEN_IN_NEW_TAB', 'Open in New Tab');
  8644.         this.terms.Add('CTLP_STR_ID_RSS_OPEN_IN_NEW_WINDOW', 'Open in New Window');
  8645.         this.terms.Add('CTLP_STR_ID_RSS_DELETE_MESSAGE', 'Delete Message');
  8646.         this.terms.Add('CTLP_STR_ID_RSS_DELETE_ALL_ITEMS_TITLE', 'Delete All Items ?');
  8647.         this.terms.Add('CTLP_STR_ID_RSS_DELETE_ALL_ITEMS_MESSAGE', 'Are you sure you want to delete all items ?');
  8648.         this.terms.Add('CTLP_STR_ID_RSS_DELETE_ALL_ITEMS_DONT_ASK_AGAIN', 'Don\'t ask again');
  8649.  
  8650.         //Multicommunity
  8651.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_MENU_COMMUNITY_TOOLBAR_DETECTED", "Community Toolbar Detected");
  8652.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_MENU_NETWORK", "Search the Conduit Network");
  8653.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_MENU_OPTIONS", "Edit");
  8654.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_COMMUNITY_DETECTED_TT", "Subscribe to this community...");
  8655.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_CAPTION", "Edit");
  8656.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_STATIC", "Here you can choose to hide or remove any of the community toolbars that you've previously added.");
  8657.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_SEARCH_HEADER", "Search the Conduit Network");
  8658.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_SEARCH_BUTT", "Search");
  8659.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_REMOVE_BUTT", "Remove");
  8660.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_MOVE_UP_BUTT", "Move Up");
  8661.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_OPTIONS_DLG_MOVE_DOWN_BUTT", "Move Down");
  8662.  
  8663.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_ADD_COMMUNITY_WARNING_INSTALL", "Download and install as a separate toolbar.");
  8664.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_MENU_COMMUNITY_SWITCH_TO_DETECTED_TOOLBAR", "Switch to -");
  8665.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_ADD_COMMUNITY_WARNING_REINSTALL", "Reinstall {TOOLBAR_NAME} toolbar");
  8666.         this.terms.Add("CTLP_STR_ID_MULTI_CHANNEL_CANDIDATE_SEARCH_FOR", "Search the Conduit Network for");
  8667.  
  8668.         this.terms.Add("CTLP_STR_ID_MULTI_COMMUNITY_ADD_WARNING_DLG_CAPTION", "Add Community Toolbar");
  8669.         this.terms.Add("CTLP_STR_ID_MULTI_COMMUNITY_ADD_WARNING_DLG_ADD", "Add instantly to my list");
  8670.         this.terms.Add("CTLP_STR_ID_MULTI_COMMUNITY_ADD_WARNING_DLG_TXT", "You can choose to instantly add the community toolbar to your list of community toolbars, or download and install it as a separate toolbar row on your browser.");
  8671.         this.terms.Add("CTLP_STR_ID_MULTI_COMMUNITY_DELETE_WARNING_DLG_CAPTION", "Remove Community Toolbar");
  8672.         this.terms.Add("CTLP_STR_ID_MULTI_COMMUNITY_DELETE_WARNING_DLG_TEXT", "Are you sure you want to remove the [TOOLBAR NAME] community toolbar from your list?");
  8673.  
  8674.  
  8675.         //new truste intermadiate dialog
  8676.         this.terms.Add("CTLP_STR_ID_ADD_COMMUNITY_DLG_TITLE", "Add to My Community Toolbar List");
  8677.         this.terms.Add("CTLP_STR_ID_ADD_COMMUNITY_DLG_EXPLAIN1", "You have chosen to instantly add a community toolbar to your list.");
  8678.         this.terms.Add("CTLP_STR_ID_ADD_COMMUNITY_DLG_EXPLAIN2", "Click OK to add and switch to the community toolbar.");
  8679.         this.terms.Add("CTLP_STR_ID_ADD_COMMUNITY_DLG_LEARN_MORE", "Learn more (includes Privacy Policy and EULA)");
  8680.  
  8681.         //Weather Dialog
  8682.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_TITLE", "Weather");
  8683.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_SELECT_LOCATION_TITLE", "Select Location");
  8684.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_CITY_NOT_FOUND", "City not found (Please type in English)");
  8685.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_SERVICE_UNAVAILABLE", "The service is temporary unavailable");
  8686.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_BTN_BACK", "Back");
  8687.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_BTN_SELECT", "Select");
  8688.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_BTN_SEARCH", "Search");
  8689.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_FEEDBACK_LINK_CAPTION", "Feedback");
  8690.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_SELECT_CITY", "Select a city from the list then click select.");
  8691.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_WEATHER_FOR", "Weather for");
  8692.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_CHANGE_LOCATION", "Change location...");
  8693.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_EXTENDED_FORCAST", "Extended forecast");
  8694.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_RIGHT_NOW", "Right now");
  8695.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_FEELS_LIKE", "Feels like:");
  8696.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_WEATHER_UNAVAILABLE", "Weather information is temporarily unavailable. Please try again later.");
  8697.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_EDITBOX_SEARCH_CITY", "Search for a country or city name");
  8698.         this.terms.Add("CTLP_STR_ID_WEATHER_DIALOG_WEATHER_CHANGE_TO", "Change to");
  8699.  
  8700.         this.terms.Add("CTLP_STR_ID_WEATHER_TOOLTIP_CAPTION", "The weather in");
  8701.         this.terms.Add("CTLP_STR_ID_WEATHER_TOOLTIP_SKY", "Sky:");
  8702.  
  8703.         this.terms.Add("CTLP_STR_ID_DEFAULT_WEATHER_BTN_TOOLTIP", "Get notified of the weather anywhere");
  8704.         this.terms.Add("CTLP_STR_ID_DEFAULT_WEATHER_BTN_LOADING_TOOLTIP", "Loading weather information");
  8705.         this.terms.Add("CTLP_STR_ID_DEFAULT_WEATHER_BTN_TEXT", "Weather");
  8706.         this.terms.Add("CTLP_STR_ID_WEATHER_NO_DATA_TXT", "No Data");
  8707.  
  8708.         //user menu items
  8709.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_CAPTION", "Manage");
  8710.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_DLG_SUB_TITLE", "Stuff you've added");
  8711.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_DLG_EXPLAIN", "You can choose which of these items to keep or remove from the toolbar.");
  8712.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_DLG_CAPTION", "Manage added items");
  8713.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_DLG_DELETE_ITEM", "Delete");
  8714.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_ADD_APPROVAL_TITLE", "Add content");
  8715.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_ADD_APPROVAL", "Click OK to add this content to the [COMPONENT NAME] menu\non the [TOOLBAR NAME] community toolbar.");
  8716.         this.terms.Add("CTLP_STR_ID_MANAGE_PRIVATE_MENU_ADD_APPROVAL2", "Click OK to add this content to the [TOOLBAR NAME] community toolbar.");
  8717.  
  8718.         //gadgets
  8719.         this.terms.Add("CTLP_STR_ID_GADGETS_ERROR_TEXT", "Sorry, this feature is experiencing temporary technical problems.Please try again soon.");
  8720.  
  8721.         //personal components
  8722.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_EMAIL", "E-mail Notifier");
  8723.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_WEATHER", "Weather");
  8724.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_RADIO", "Radio Player");
  8725.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_INTRO", "Want to add these personalized buttons to your toolbar?");
  8726.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_INTRO_SINGLE", "Want to add this personalized button to your toolbar?");
  8727.  
  8728.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_SETTINGS_TITLE_FF", "Please configure the settings below; you can change them at any time.");
  8729.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_SET_SEARCH_FF", "Set IObitCom customized Web Search as my default");
  8730.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_SET_HOMEPAGE_FF", "Set my homepage to the IObitCom customized Web Search page");
  8731.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_BOTTOM_FF", "For more information about the community toolbar, please view our");
  8732.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_ABORT_INSTALLATION_FF", "Abort installation");
  8733.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_FINISH_FF", "Finish");
  8734.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_CONFIRM_UNINSTALL_BODY_FF", "Are you sure you want to abort the installation?\nIf you do, then the community toolbar will not appear\nthe next time you open your browser.");
  8735.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_WELCOME_ONLY_TITLE_FF", "Congratulations, you now have the IObitCom toolbar installed.");
  8736.         
  8737.  
  8738.         //********* new mystuff  ************
  8739.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ADD_STUFF_TOOLTIP", "Add Stuff: Get cool components for your toolbar");
  8740.         this.terms.Add("CTLP_STR_ID_MYSTUFF_MANAGE_TOOLTIP", "Move or delete the components you added to your toolbar");
  8741.         this.terms.Add("CTLP_STR_ID_MYSTUFF_MANAGE_CAPTION", "Manage");
  8742.         //add component confirm
  8743.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_COMPONENT_CONFIRM_TITLE", "Add Toolbar Component");
  8744.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_COMPONENT_CONFIRM_TEXT", "Are you sure you want to add [COMPONENT NAME] to your community toolbar?");
  8745.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_COMPONENT_CONFIRM_TITLE_EXISTS", "Add Toolbar Component");
  8746.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_COMPONENT_CONFIRM_TEXT_EXISTS", "You have already added [COMPONENT NAME] to your community toolbar. Would you like to update it?");
  8747.         //add alert confirm
  8748.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_ALERT_CONFIRM_TITLE", "Add Desktop Alerts");
  8749.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_ALERT_CONFIRM_TEXT", "Are you sure you want to receive [ALERTS NAME]?");
  8750.         this.terms.Add("CTLP_STR_ID_MYSTUFF_API_ADD_ALERT_CONFIRM_ALERT_DISABLED_TEXT", "To receive [ALERTS NAME], your Alerts setting must be enabled. Would you like us to enable it for you?");
  8751.         //tooltips
  8752.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_COMP_NOT_EXISTS", "We're sorry, the toolbar component is no longer available.");
  8753.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_TEMP_UNAVAILABLE", "We're sorry, the toolbar component is temporarily unavailable. Please try again soon.");
  8754.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_TECH_ERROR", "There seems to be a problem with the toolbar component. Please try again. If the problem persists,");
  8755.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_CUSTOMER_SUPPORT_LINK_TEXT", "contact customer support");
  8756.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_UPGRADE_TOOLBAR_FULL_MSG", "To add the toolbar component, you need to upgrade your community toolbar version and then try adding the component again.");
  8757.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_UPGRADE_TOOLBAR_LINK_TEXT", "Upgrade");
  8758.  
  8759.         //tooltips titles
  8760.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_TITLE_UNVAVAILABLE", "Component Unavailable");
  8761.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_TITLE_TEMP_UNAVAILABLE", "Component Temporarily Unavailable");
  8762.         this.terms.Add("CTLP_STR_ID_MYSTUFF_ERROR_TOOLTIP_TITLE_UPGRADE", "Upgrade Community Toolbar");
  8763.  
  8764.         //search engine
  8765.         this.terms.Add("CTLP_STR_ID_MYSTUFF_SEARCH_ENGINE_CAPTION", "Toolbar components");
  8766.  
  8767.         //twitter
  8768.         this.terms.Add("CTLP_STR_ID_TWITTER_REFRESH_TWEETS_TOOLTIP", "Refresh Tweets");
  8769.         this.terms.Add("CTLP_STR_ID_TWITTER_DELETE_ALL_TWEETS_TOOLTIP", "Delete All Tweets");
  8770.         this.terms.Add("CTLP_STR_ID_TWITTER_ARE_YOU_SURE_DELETE_ALL_TWEETS", "Are you sure you want to delete all the tweets?");
  8771.  
  8772.         //privacy
  8773.         this.terms.Add("CTLP_STR_ID_POPUP_BLOCKER_CLEAR_CASHE_APPROVAL_MSGBOX", "You are about to clear your browser's cache. Do you want to continue?");
  8774.         this.terms.Add("CTLP_STR_ID_POPUP_BLOCKER_CLEAR_HISTORY_APPROVAL_MSGBOX", "You are about to clear your browser's history. Do you want to continue?");
  8775.         this.terms.Add("CTLP_STR_ID_POPUP_BLOCKER_CLEAR_COOKIES_APPROVAL_MSGBOX", "You are about to delete your browser's cookies. Do you want to continue?");
  8776.  
  8777.         //facebook
  8778.         this.terms.Add("CTLP_STR_ID_FACEBOOK_COMPONENT_LOGIN_TEXT", "Login");
  8779.         this.terms.Add("CTLP_STR_ID_FACEBOOK_COMPONENT_LOGGED_OUT_HINT", "Log in to your Facebook toolbar component");
  8780.         this.terms.Add("CTLP_STR_ID_FACEBOOK_COMPONENT_LOGGED_IN_HINT", "You're logged in to your Facebook toolbar component");
  8781.  
  8782.         this.terms.Add("CTLP_STR_ID_OPTIONS_DLG_FACEBOOK_COMP_TITLE", "Facebook");
  8783.         this.terms.Add("CTLP_STR_ID_OPTIONS_DLG_FACEBOOK_COMP_DESCRIPTION", "Open any Facebook page in a click and get alerts with your new messages and updates.");
  8784.         this.terms.Add("CTLP_STR_ID_OPTIONS_DLG_FACEBOOK_SETTINGS_BUTTON", "Facebook Settings...");
  8785.  
  8786.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_FACEBOOK_SINGLE", "Add the Facebook button");
  8787.         this.terms.Add("CTLP_STR_ID_PERSONAL_COMP_DLG_FACEBOOK", "Facebook");
  8788.  
  8789.         this.terms.Add("CTLP_STR_ID_FACEBOOK_LOGOUT_DIALOG_TITLE", "Facebook | Logout");
  8790.         this.terms.Add("CTLP_STR_ID_FACEBOOK_LOGOUT_DIALOG_TEXT", "Are you sure you want to log out of your Facebook toolbar component?");
  8791.  
  8792.         //facebook settings dialog
  8793.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_SETTING_TITLE", "Alert Settings");
  8794.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_DLG_TITLE", "Facebook | Settings");
  8795.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_ALERT_INBOX", "New Message");
  8796.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_ALERT_FRIEND_REQUEST", "Friend Request");
  8797.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_ALERT_GROUP", "Group Invitation");
  8798.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_ALERT_EVENTS", "Event Invitation");
  8799.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_ALERT_NEWS_FEED", "News Feed Update");
  8800.  
  8801.         //this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_DLG_SUBTITLE", "Choose the alerts you wish to recieve");
  8802.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_DLG_SUBTITLE_FIRST", "Would you like to receive alerts from Facebook?");
  8803.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_DLG_SUBTITLE_SECOND", "Make your selections below:");
  8804.         
  8805.         this.terms.Add("CTLP_STR_ID_FACEBOOK_SETTINGS_CHOOSE_FROM_OPTIONS", "Yes, send me Facebook alerts");
  8806.         //facebook alerts
  8807.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_TITLE", "New Message");
  8808.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_FRIENDS_TITLE", "Friend Request");
  8809.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_GROUPS_TITLE", "Group Invitation");
  8810.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_EVENTS_TITLE", "Event Invitation");
  8811.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_NEWS_FEED_TITLE", "News Feed Update");
  8812.  
  8813.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_GENERAL_HTML", "You have a <a EB_FB_LINK1>new message</a> in your Inbox.");
  8814.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_INBOX_HTML", "<a EB_FB_LINK1>EB_FB_USER_NAME</a> has sent you a <a EB_FB_LINK2>new message</a>");
  8815.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_FRIENDS_HTML", "<a EB_FB_LINK1>EB_FB_USER_NAME</a> has sent you a <a EB_FB_LINK2>friend request</a>");
  8816.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_GROUPS_HTML", "You have been invited to join <a EB_FB_LINK1>EB_FB_GROUP_NAME</a>");
  8817.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_EVENTS_HTML", "You have been invited to attend <a EB_FB_LINK1>EB_FB_EVENT_NAME</a>");
  8818.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_HEADER", "[TOOLBAR_NAME] Alerts");
  8819.  
  8820.         this.terms.Add("CTLP_STR_ID_FACEBOOK_STATUS_GADGET_STATUS_TXT", "Status");
  8821.         this.terms.Add("CTLP_STR_ID_FACEBOOK_STATUS_GADGET_CLEAR_TXT", "Clear");
  8822.         this.terms.Add("CTLP_STR_ID_FACEBOOK_STATUS_GADGET_POST_TXT", "Post");
  8823.         this.terms.Add("CTLP_STR_ID_FACEBOOK_STATUS_GADGET_CANCEL_TXT", "Cancel");
  8824.         this.terms.Add("CTLP_STR_ID_FACEBOOK_STATUS_GADGET_INPUT_TXT", "What's on your mind?");
  8825.  
  8826.         this.terms.Add("CTLP_STR_ID_FACEBOOK_ALERT_MORE", "More >>");
  8827.  
  8828.     },
  8829.  
  8830.     GetByID: function(key) {
  8831.         if (!this.terms.Contains(key)) return "";
  8832.         else return this.terms.GetByID(key);
  8833.     }
  8834. };
  8835.  
  8836. LanguagePackDefaults.init();
  8837.  
  8838. function LanguagePackDS(xmlLanguagePack) {
  8839.     this.locale = "";
  8840.     this.lastUpdateTime = 0;
  8841.     var terms = new HashArray();
  8842.  
  8843.     this.init = function() {
  8844.         this.locale = XML.GetSingleNodeValue(xmlLanguagePack, "LOCALE").toLowerCase();
  8845.         var newLut = XML.GetSingleNodeValue(xmlLanguagePack, "LAST_UPDATE_TIME", 0);
  8846.         //bug fix, old version saved as LAST_UPDATE
  8847.         var oldLut = XML.GetSingleNodeValue(xmlLanguagePack, "LAST_UPDATE", 0);
  8848.         this.lastUpdateTime = (newLut) ? newLut : oldLut;
  8849.         var xmlTerms = XML.SelectSingleNode(xmlLanguagePack, "TRANSLATED_KEYS");
  8850.         if (!xmlTerms || xmlTerms.childNodes.length == 0) return;
  8851.  
  8852.         var xmlTerm = null;
  8853.         var key, translation;
  8854.         for (var i = 0; i < xmlTerms.childNodes.length; i++) {
  8855.             xmlTerm = xmlTerms.childNodes[i];
  8856.             key = XML.GetSingleNodeValue(xmlTerm, "KEY_ID");
  8857.             translation = XML.GetSingleNodeValue(xmlTerm, "TRANSLATION");
  8858.             if (key && translation) {
  8859.                 terms.Add(key, XML.FromLegalXml(translation));
  8860.             }
  8861.         }
  8862.     };
  8863.  
  8864.     this.GetByID = function(key, locale) {
  8865.         if (!locale || locale.toLowerCase() != this.locale || !terms.Contains(key))
  8866.             return LanguagePackDefaults.GetByID(key);
  8867.  
  8868.         return terms.GetByID(key);
  8869.     };
  8870.  
  8871.     //get by id without locale
  8872.     this.GetByIDNL = function(key) {
  8873.         return (terms.Contains(key)) ? terms.GetByID(key) : LanguagePackDefaults.GetByID(key);
  8874.     };
  8875.     
  8876.     if (xmlLanguagePack)
  8877.         this.init();
  8878. };
  8879. function ComponentsIDs() {
  8880.     this.MainMenu = '100';
  8881.     this.SearchBox = '101';
  8882.     this.Highlighter = '102';
  8883.     this.EMailNotifier = '103';
  8884.     this.Privacy = '104';
  8885.     this.Weather = '105';
  8886.     this.Radio = '107';
  8887.     this.Facebook = '116';
  8888.     this.MultiCommunity = '200';
  8889.     this.Chevron = "201";
  8890.     this.ChevronMyStuff = "202";
  8891.     this.MyStuffSplitter = "203";
  8892.     this.Chat = '';
  8893.     this.MyStuffAddButton = "204";
  8894.     this.MyStuffOptionsButton = "205";
  8895. };
  8896. function GeneralToolbarInfo(XMLGeneralInfo, actingCTID, originalCTID, objToolbarDefaults) {
  8897.     var fix404Flag = false;
  8898.     var WEATHER_COMPONENT_TAG_NAME = "WEATHER";
  8899.     var EMAIL_COMPONENT_TAG_NAME = "EMAIL_NOTIFIER";
  8900.     var RADIO_COMPONENT_TAG_NAME = "RADIO_PLAYER";
  8901.     var PRIVACY_COMPONENT_TAG_NAME = "PRIVACY_COMPONENT";
  8902.  
  8903.     this.style = null;
  8904.     this.skin = new ToolbarSkin(null, new ToolbarStyle(), null, objToolbarDefaults.chromeName);
  8905.     this.writeToUsCmd = "";
  8906.     this.toolbarAlignMode = "";
  8907.     this.toolbarName = "";
  8908.     this.allowNonPrivacyFunctions = null; //boolean
  8909.     this.displayTrusteSeal = null; //boolean
  8910.     this.webServerUrl = "";
  8911.     this.myWebServerUrl = "";
  8912.     this.tellAfriendCmd = "";
  8913.     this.fixPageNotFoundUrl = "";
  8914.     this.userComponentsState = new UserComponentsState();
  8915.     
  8916.     this.myStuffEnabled = true;
  8917.     this.myStuffBlinkBGColor = "";
  8918.     this.myStuffPublisherMinWidth = "";
  8919.  
  8920.     this.searchInNewTabEnabled = false;
  8921.     this.searchInNewTabServiceUrl = "";
  8922.  
  8923.     this._init = function() {
  8924.         var xmlUserComponentsState = XML.SelectSingleNode(XMLGeneralInfo, "USER_COMPONENTS_STATE");
  8925.         var xmlUserComponentsVisibilityFlags = XML.SelectSingleNode(XMLGeneralInfo, "USER_COMPONENTS_VISIBILITY_FLAGS");
  8926.         this.handleUserComponents(xmlUserComponentsState, xmlUserComponentsVisibilityFlags);
  8927.         this.style = new ToolbarStyle(XML.SelectSingleNode(XMLGeneralInfo, "FONT"));
  8928.  
  8929.         this.writeToUsCmd = XML.GetSingleNodeValue(XMLGeneralInfo, "WRITE_TO_US_CMD");
  8930.         this.toolbarAlignMode = XML.GetSingleNodeValue(XMLGeneralInfo, "ALIGN_MODE");
  8931.         this.toolbarName = XML.GetSingleNodeValue(XMLGeneralInfo, "TOOLBAR_NAME");
  8932.         this.allowNonPrivacyFunctions = XML.GetSingleNodeValueAsBoolean(XMLGeneralInfo, "ALLOW_NON_PRIVACY_FUNCTIONS", true);
  8933.         this.displayTrusteSeal = XML.GetSingleNodeValueAsBoolean(XMLGeneralInfo, "DISPLAY_TRUSTE_SEAL", false);
  8934.         this.webServerUrl = XML.GetSingleNodeValue(XMLGeneralInfo, "WEB_SERVER_URL", objToolbarDefaults.webServerUrl);
  8935.         this.myWebServerUrl = XML.GetSingleNodeValue(XMLGeneralInfo, "MY_WEB_SERVER_URL");
  8936.         //tell a friend
  8937.         var xmlTellAfriend = XML.SelectSingleNode(XMLGeneralInfo, "TELL_A_FRIEND");
  8938.         if (xmlTellAfriend)
  8939.             this.tellAfriendCmd = XML.GetSingleNodeValue(xmlTellAfriend, "CMD");
  8940.  
  8941.         //mystuff enabled
  8942.         this.myStuffEnabled = XML.GetSingleNodeValueAsBoolean(XMLGeneralInfo, "MY_STUFF_ENABLED", true);
  8943.  
  8944.         //mystuff blink bg color
  8945.         var xpathResult = XMLGeneralInfo.ownerDocument.evaluate("MY_STUFF/BLINK_BG_COLOR", XMLGeneralInfo, null, 2, null);
  8946.         if (xpathResult && xpathResult.stringValue) this.myStuffBlinkBGColor = xpathResult.stringValue;
  8947.  
  8948.         //mystuff publisher min width
  8949.         xpathResult = XMLGeneralInfo.ownerDocument.evaluate("MY_STUFF/PUBLISHER_RESERVED_AREA_PX", XMLGeneralInfo, null, 2, null);
  8950.         if (xpathResult && xpathResult.stringValue) this.myStuffPublisherMinWidth = parseInt(xpathResult.stringValue);
  8951.  
  8952.         //fix page not found 404
  8953.         var defaultFixPageNotFoundUrl = this.webServerUrl + stringFormat("notfound/?actid={0}&octid={1}&url=EB_MAIN_FRAME_URL", actingCTID, originalCTID);
  8954.         this.fixPageNotFoundUrl = XML.GetSingleNodeValue(XMLGeneralInfo, "FIX_PAGE_NOT_FOUND_ERROR_URL", defaultFixPageNotFoundUrl);
  8955.         this.fixPageNotFoundUrl = URL.AddHTTPProtocol(this.fixPageNotFoundUrl);
  8956.  
  8957.         //replace aliases
  8958.         this.fixPageNotFoundUrl = this.fixPageNotFoundUrl.replace(ToolbarDataParsingXPCOM.consts.aliases.ToolbarID, actingCTID);
  8959.         this.fixPageNotFoundUrl = this.fixPageNotFoundUrl.replace(ToolbarDataParsingXPCOM.consts.aliases.ToolbarOriginalID, originalCTID);
  8960.  
  8961.         //search in new tab
  8962.         var xmlNewTab = XML.SelectSingleNode(XMLGeneralInfo, "SEARCH_IN_TAB_SERVICE");
  8963.         if (xmlNewTab) {
  8964.             this.searchInNewTabEnabled = XML.GetSingleNodeValueAsBoolean(xmlNewTab, "ENABLED", false);
  8965.             this.searchInNewTabServiceUrl = XML.GetSingleNodeValue(xmlNewTab, "SERVICE_URL");
  8966.         }
  8967.         //skin info
  8968.         var xmlSkinInfo = XML.SelectSingleNode(XMLGeneralInfo, "SKIN");
  8969.         this.skin = new ToolbarSkin(xmlSkinInfo, this.style , this.myStuffBlinkBGColor ,objToolbarDefaults.chromeName);
  8970.  
  8971.     };
  8972.  
  8973.     this.handleUserComponents = function(xmlUserComponentsState, xmlUserComponentsVisibilityFlags) {
  8974.         var oComp = null;
  8975.  
  8976.         oComp = this._getPersonalComponentVisibilityFlags(xmlUserComponentsVisibilityFlags, xmlUserComponentsState, WEATHER_COMPONENT_TAG_NAME);
  8977.         if (oComp) this.userComponentsState.weather = oComp;
  8978.  
  8979.         oComp = this._getPersonalComponentVisibilityFlags(xmlUserComponentsVisibilityFlags, xmlUserComponentsState, RADIO_COMPONENT_TAG_NAME);
  8980.         if (oComp) this.userComponentsState.radio = oComp;
  8981.  
  8982.         oComp = this._getPersonalComponentVisibilityFlags(xmlUserComponentsVisibilityFlags, xmlUserComponentsState, EMAIL_COMPONENT_TAG_NAME);
  8983.         if (oComp) this.userComponentsState.emailNotifier = oComp;
  8984.  
  8985.         oComp = this._getPersonalComponentVisibilityFlags(xmlUserComponentsVisibilityFlags, xmlUserComponentsState, PRIVACY_COMPONENT_TAG_NAME);
  8986.         if (oComp) this.userComponentsState.privacy = oComp;
  8987.     };
  8988.  
  8989.     this._getPersonalComponentVisibilityFlags = function(xmlFlags, xmlUserComponentsState, tagName) {
  8990.         if (!xmlFlags && !xmlUserComponentsState) return null;
  8991.  
  8992.         var oComponent = null;
  8993.         if (xmlFlags) {
  8994.             var xmlState = XML.SelectSingleNode(xmlFlags, tagName);
  8995.             if (xmlState) {
  8996.                 var isAvailable = XML.GetSingleNodeValueAsBoolean(xmlState, "AVAILABLE", null);
  8997.                 var isChecked = XML.GetSingleNodeValueAsBoolean(xmlState, "CHECKED", null);
  8998.                 oComponent = new UserComponentState(isAvailable, isChecked);
  8999.             }
  9000.         }
  9001.         if (!oComponent) {
  9002.             if (!xmlUserComponentsState)
  9003.                 return null;
  9004.             else {
  9005.                 oComponent = new UserComponentState(true, null);
  9006.                 oComponent.checked = XML.GetSingleNodeValueAsBoolean(xmlUserComponentsState, tagName, true);
  9007.             }
  9008.         }
  9009.         else if (oComponent.checked == null && xmlUserComponentsState)
  9010.             oComponent.checked = XML.GetSingleNodeValueAsBoolean(xmlUserComponentsState, tagName, true);
  9011.             
  9012.         return oComponent;
  9013.     };
  9014.  
  9015.     if (XMLGeneralInfo)
  9016.         this._init();
  9017. };
  9018. function LogoIconItem(xmlLogoIcon) {
  9019.     this.tooltip = "";
  9020.     this.link = "";
  9021.     this.path = "";
  9022.  
  9023.     this._init = function() {
  9024.         this.tooltip = XML.GetSingleNodeValue(xmlLogoIcon, "TOOLTIP");
  9025.         this.link = URL.LegalizeLinkUrl(XML.GetSingleNodeValue(xmlLogoIcon, "LINK"));
  9026.         this.path = URL.AddHTTPProtocol(XML.GetSingleNodeValue(xmlLogoIcon, "PATH"));
  9027.     };
  9028.  
  9029.     if (xmlLogoIcon)
  9030.         this._init();
  9031.  
  9032. };
  9033. function MyStuffComponentData() {
  9034.     this.lastUpdateTime = "";
  9035.     this.lastCheckTime = "";
  9036.     this.compGuid = "";
  9037.     this.compInstanceGuid = "";
  9038.     this.uniqueCompId = "";
  9039.     this.isDynamic = true;
  9040.  
  9041.     //fills this instance and returns component's xml
  9042.     this.initFromXml = function(xmlMyStuffComponent) {
  9043.         if (!xmlMyStuffComponent) return;
  9044.  
  9045.         this.lastUpdateTime = XML.GetSingleNodeValue(xmlMyStuffComponent, "LAST_UPDATE_TIME");
  9046.         this.lastCheckTime = XML.GetSingleNodeValue(xmlMyStuffComponent, "LAST_CHECK_TIME");
  9047.         this.compGuid = XML.GetSingleNodeValue(xmlMyStuffComponent, "COMPONENT_GUID");
  9048.         this.compInstanceGuid = XML.GetSingleNodeValue(xmlMyStuffComponent, "COMPONENT_INSTANCE_GUID");
  9049.         this.isDynamic = XML.GetSingleNodeValue(xmlMyStuffComponent, "IS_DYNAMIC");
  9050.         var xmlComponent = XML.SelectSingleNode(xmlMyStuffComponent, "COMPONENT_XML");
  9051.         
  9052.         if (xmlComponent.childNodes.length == 1)
  9053.             xmlComponent = xmlComponent.firstChild;
  9054.         else {
  9055.             for (var i = 0; i < xmlComponent.childNodes.length; i++) {
  9056.                 if (xmlComponent.childNodes[i].tagName) {
  9057.                     xmlComponent = xmlComponent.childNodes[i];
  9058.                     break;
  9059.                 }
  9060.             }
  9061.         }
  9062.         this.uniqueCompId = XML.GetSingleNodeValue(xmlComponent, "UNIQUE_COMP_ID");
  9063.         return xmlComponent;
  9064.     };
  9065.  
  9066.     this.updateFromResponse = function(objMyStuffRS) {
  9067.         if (!objMyStuffRS) return;
  9068.  
  9069.         this.lastUpdateTime = objMyStuffRS.lastUpdateTime;
  9070.         this.lastCheckTime = Date.parse(Date());
  9071.         this.isDynamic = true;
  9072.         this.compInstanceGuid = objMyStuffRS.compInstanceGuid;
  9073.         var xmlComponent = objMyStuffRS.xmlComponent;
  9074.         return xmlComponent;
  9075.     };
  9076.  
  9077.     this.toXml = function(xmlComponent) {
  9078.         var strXml = "<COMPONENT/>";
  9079.         var xmlDoc = XML.GetXmlDocument(strXml);
  9080.         var xmlRoot = xmlDoc.documentElement;
  9081.  
  9082.         if (this.isDynamic) {
  9083.             xmlRoot.appendChild(XML.CreateXmlTextNode(xmlDoc, "LAST_UPDATE_TIME", this.lastUpdateTime));
  9084.             xmlRoot.appendChild(XML.CreateXmlTextNode(xmlDoc, "LAST_CHECK_TIME", this.lastCheckTime));
  9085.         }
  9086.  
  9087.         xmlRoot.appendChild(XML.CreateXmlTextNode(xmlDoc, "COMPONENT_GUID", this.compGuid));
  9088.         xmlRoot.appendChild(XML.CreateXmlTextNode(xmlDoc, "COMPONENT_INSTANCE_GUID", this.compInstanceGuid));
  9089.         xmlRoot.appendChild(XML.CreateXmlTextNode(xmlDoc, "IS_DYNAMIC", this.isDynamic.toString()));
  9090.         var xmlCompNode = xmlDoc.createElement("COMPONENT_XML");
  9091.         xmlCompNode.appendChild(xmlComponent);
  9092.         xmlRoot.appendChild(xmlCompNode);
  9093.         return xmlRoot;
  9094.     };
  9095. };
  9096. function ToolbarData() {
  9097.     this.publisherItemsHash = null; //settings components
  9098.     this.userItemsHash = null;
  9099.     this.thirdPartyItemsHash = null;
  9100.     
  9101.     this.myStuffItemsHash = null; //key - UniqueCompID
  9102.     this.myStuffDataHash = null; //key - compGuid - for API
  9103.     this.myStuffUniqueCompIdToCompGuidHash = null;
  9104.     
  9105.     this.generalToolbarInfo = null;
  9106.     this.componentsIds = null;
  9107.     
  9108.     //init default LP
  9109.     this.languagePack = new LanguagePackDS(null);
  9110.  
  9111.     this.getItem = function(uniqueCompID) {
  9112.         if (this.publisherItemsHash && this.publisherItemsHash.Count() > 0 && this.publisherItemsHash.Contains(uniqueCompID))
  9113.             return this.publisherItemsHash.GetByID(uniqueCompID);
  9114.  
  9115.         if (this.userItemsHash && this.userItemsHash.Count() > 0 && this.userItemsHash.Contains(uniqueCompID))
  9116.             return this.userItemsHash.GetByID(uniqueCompID);
  9117.  
  9118.         if (this.thirdPartyItemsHash && this.thirdPartyItemsHash.Count() > 0 && this.thirdPartyItemsHash.Contains(uniqueCompID))
  9119.             return this.thirdPartyItemsHash.GetByID(uniqueCompID);
  9120.  
  9121.         if (this.myStuffItemsHash && this.myStuffItemsHash.Count() > 0 && this.myStuffItemsHash.Contains(uniqueCompID))
  9122.             return this.myStuffItemsHash.GetByID(uniqueCompID);
  9123.  
  9124.         return null;
  9125.     };
  9126.  
  9127.     this.getEmailNotifierItem = function() {
  9128.         return this.getItem(this.componentsIds.EMailNotifier);
  9129.     };
  9130.  
  9131.     this.getWeatherItem = function() {
  9132.         return this.getItem(this.componentsIds.Weather);
  9133.     };
  9134.  
  9135.     this.getPrivacyItem = function() {
  9136.         return this.getItem(this.componentsIds.Privacy);
  9137.     };
  9138.  
  9139.     this.getRadioItem = function() {
  9140.         return this.getItem(this.componentsIds.Radio);
  9141.     };
  9142.  
  9143.     this.getFacebookItem = function() {
  9144.         return this.getItem(this.componentsIds.Facebook);
  9145.     };
  9146. };
  9147. function ToolbarItemData(xmlNode, compType, isPublisher, chromeName, originalCTID, actingCTID) {
  9148.     this.xmlNode = xmlNode;
  9149.     this.compType = compType;
  9150.     this.isPublisher = isPublisher;
  9151.     this.chromeName = chromeName;
  9152.     this.originalCTID = originalCTID;
  9153.     this.actingCTID = actingCTID;
  9154. };
  9155. function Button(objData) {
  9156.     this.text = "";
  9157.     this.image = "";
  9158.     this.tooltip = "";
  9159.     this.type = "";
  9160.  
  9161.     //for POPHTML
  9162.     this.data = null;
  9163.  
  9164.     this.InitWithXML = function(XMLNode) {
  9165.         var XMLRoot = XMLNode.ownerDocument ? XMLNode : XMLNode.documentElement;
  9166.         var XMLChildNode = null;
  9167.  
  9168.         for (var i = 0; i < XMLRoot.childNodes.length; i++) {
  9169.             var XMLChildNode = XMLRoot.childNodes[i];
  9170.             if (XMLChildNode.tagName == "DEFAULT_BUTTON_TEXT") {
  9171.                 this.text = XML.GetXmlNodeValue(XMLChildNode);
  9172.             }
  9173.             else if (XMLChildNode.tagName == "BUTTON_ICON_URL") {
  9174.                 this.image = XML.GetXmlNodeValue(XMLChildNode);
  9175.                 if (this.image) {
  9176.                     var oManager = DefaultsXPCOM.getManager(objData.chromeName, objData.originalCTID);
  9177.                     this.image = oManager.getImageUrl(this.image);
  9178.                 }
  9179.             }
  9180.             else if (XMLChildNode.tagName == "BUTTON_TOOLTIP") {
  9181.                 this.tooltip = XML.GetXmlNodeValue(XMLChildNode);
  9182.             }
  9183.             else if (XMLChildNode.tagName == "DATA") {
  9184.                 this.data = ToolbarDataParsingXPCOM.dataNodeFactory.getDataObject(XMLChildNode);
  9185.                 if (this.data.isValid())
  9186.                     this.type = this.data.type;
  9187.             }
  9188.         }
  9189.     };
  9190. };
  9191. function BaseToolbarItem(objData) {
  9192.     this.objData = objData;
  9193.     this.UniqueCompID = "";
  9194.     this.CompType = "";
  9195.     this.DisplayText = "";
  9196.     this.DisplayIcon = "";
  9197.  
  9198.     this.isPersonalComponent = false;
  9199.     this.isMustHaveComponents = false;
  9200.     this.personalComponentState = null;
  9201.  
  9202.     this.Permission = ToolbarDataParsingXPCOM.Editable.FULL;
  9203.     this.ShowInChevron = true;
  9204.  
  9205.     this.initCompType = function() {
  9206.         this.CompType = this.objData.compType;
  9207.     };
  9208.  
  9209.     this.parseCommonData = function() {
  9210.         this.UniqueCompID = XML.GetSingleNodeValue(this.objData.xmlNode, "UNIQUE_COMP_ID", "");
  9211.         this.DisplayText = XML.GetSingleNodeValue(this.objData.xmlNode, "DISPLAY_TEXT", this.DisplayText);
  9212.         this.DisplayIcon = XML.GetSingleNodeValue(this.objData.xmlNode, "DISPLAY_ICON", this.DisplayIcon);
  9213.         if (this.DisplayIcon)
  9214.             this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  9215.     };
  9216.  
  9217.     this.parse = function() {
  9218.         //implement in inherited class
  9219.     };
  9220.  
  9221.     this.parseUserAttributes = function() {
  9222.         if (this.isPersonalComponent) {
  9223.             this.Permission = ToolbarDataParsingXPCOM.Editable.NONE;
  9224.             this.CompType = ToolbarDataParsingXPCOM.ComponentType.Settings;
  9225.         }
  9226.         else {
  9227.             var xmlUserAttributes = XML.SelectSingleNode(this.objData.xmlNode, "USER_ATTRIBUTES");
  9228.             if (!xmlUserAttributes) return;
  9229.             
  9230.             var permission = XML.GetSingleNodeValue(xmlUserAttributes, "PERMISSION");
  9231.             if (permission) this.Permission = permission;
  9232.             this.ShowInChevron = XML.GetSingleNodeValueAsBoolean(xmlUserAttributes, "SHOW_IN_CHEVRON", this.ShowInChevron);
  9233.         }
  9234.     };
  9235.  
  9236.     this.validateUniqueCompID = function() {
  9237.         if (!this.UniqueCompID)
  9238.             this.UniqueCompID = Math.random() * 10;
  9239.     };
  9240.  
  9241.     this.validateTextAndIcon = function() {
  9242.         //implement in inherited class
  9243.     };
  9244.  
  9245.     this._getVisiblePrefName = function() {
  9246.         var strPrefName = this.objData.originalCTID + ".";
  9247.         if (!this.isPersonalComponent && this.objData.originalCTID != this.objData.actingCTID)
  9248.             strPrefName += this.objData.actingCTID + "."
  9249.  
  9250.         strPrefName += (this.objData.compType == ToolbarDataParsingXPCOM.ComponentType.MyStuff) ? "MyStuffComponents." : "components.";
  9251.         strPrefName += this.UniqueCompID;
  9252.         return strPrefName;
  9253.     };
  9254.  
  9255.     this.isShow = function() {
  9256.         if (this.isMustHaveComponents) return true;
  9257.         if (!this.isAvailable) return false;
  9258.  
  9259.         var strPrefName = this._getVisiblePrefName();
  9260.         var hasUserValue = PrefService.HasUserValue(strPrefName);
  9261.         var userValue = PrefService.GetPref(strPrefName);
  9262.  
  9263.         //regular components
  9264.         if (!this.isPersonalComponent) {
  9265.             if (hasUserValue) return userValue;
  9266.             else if (this.CompType == ToolbarDataParsingXPCOM.ComponentType.ThirdParty) return false;
  9267.             else return true;
  9268.         }
  9269.         //personal components
  9270.         else
  9271.             return this.isShowPersonalComponent(hasUserValue, userValue);
  9272.     };
  9273.  
  9274.     this.setShowState = function(bIsShown) {
  9275.         var strPrefName = this._getVisiblePrefName();
  9276.         PrefService.SetPref(strPrefName, bIsShown);
  9277.     };
  9278.  
  9279.     // +++++++++++++ personal components functions ++++++++++++++++
  9280.     //is show component (in case of personal component, used internally
  9281.     this.isShowPersonalComponent = function(hasUserValue, userValue) {
  9282.         //not avaliable, don't show
  9283.         if (!this.isAvailable()) return false;
  9284.         //has user value, show according it
  9285.         if (hasUserValue) return userValue;
  9286.         //publisher component, and not disabled by user
  9287.         if (this.objData.isPublisher) return true;
  9288.  
  9289.         var firstTimePrefName = this.objData.originalCTID + "." + LoginPrefConsts.FirstTime;
  9290.         var isFirstTime = (PrefService.GetPref(firstTimePrefName) == true) ? false : true;
  9291.         //don't show personal component, unless it's publisher added, before user accepted welcome dialog
  9292.         if (isFirstTime) return false;
  9293.         //default value, user didn't change it
  9294.         else return this.personalComponentState.checked;
  9295.     };
  9296.     
  9297.     //is available in options dialog
  9298.     this.isAvailable = function() {
  9299.         if (!this.isPersonalComponent || !this.personalComponentState) return true;
  9300.  
  9301.         if (this.objData.isPublisher) return true;
  9302.         return this.personalComponentState.available;
  9303.     };
  9304.  
  9305.     this.isShowInPersonalComponentsDialog = function() {
  9306.         if (this.objData.isPublisher)
  9307.             return false;
  9308.         else
  9309.             return this.personalComponentState.available && this.personalComponentState.checked;
  9310.     };
  9311.  
  9312.     this.isCheckedInPersonalComponentsDialog = function() {
  9313.         if (!this.isShowInPersonalComponentsDialog())
  9314.             return false;
  9315.         else
  9316.             return this.personalComponentState.checked;
  9317.     };
  9318.     // +++++++++++++ personal components functions end ++++++++++++++++
  9319.  
  9320.     this.init = function() {
  9321.         this.initCompType();
  9322.         this.parseCommonData();
  9323.         this.parse();
  9324.         this.parseUserAttributes();
  9325.         this.validateUniqueCompID();
  9326.         this.validateTextAndIcon();
  9327.     };
  9328. };
  9329. function BrowserItem(objData) {
  9330.     this.objData = objData;
  9331.     
  9332.     this.width = "150"; //default value
  9333.     this.height = "20";
  9334.     this.url = "";
  9335.     this.strId = "";
  9336.     
  9337.     this.parse = function() {
  9338.         var xmlNode = this.objData.xmlNode;
  9339.         //set the attributes
  9340.         this.width = XML.GetSingleNodeValue(xmlNode, "WIDTH");
  9341.         this.url = XML.GetSingleNodeValue(xmlNode, "URL");
  9342.         this.url = XML.FromLegalXml(this.url);
  9343.         this.DisplayText = XML.GetSingleNodeValue(xmlNode, "DISPLAY_TEXT");
  9344.         this.DisplayIcon = XML.GetSingleNodeValue(xmlNode, "DISPLAY_ICON");
  9345.         this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  9346.     };
  9347.  
  9348.     this.validateTextAndIcon = function() {
  9349.         if (!this.DisplayText)
  9350.             this.DisplayText = "Browser Component";
  9351.  
  9352.         if (!this.DisplayIcon)
  9353.             this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/minibrowser.png";
  9354.     };
  9355.     
  9356.     this.init();
  9357. };
  9358.  
  9359. BrowserItem.prototype = new BaseToolbarItem();
  9360. function ButtonItem(objData) {
  9361.     this.objData = objData;
  9362.     this.button = new Button(objData);
  9363.  
  9364.     this.parse = function() {
  9365.         var xmlNode = this.objData.xmlNode;
  9366.         //set the type
  9367.         var strTagName = xmlNode.tagName;
  9368.         var bSpecialCommandItem = false;
  9369.         switch (strTagName) {
  9370.             case "LINK_BUTTONITEM": this.button.type = "LINK"; break;
  9371.             case "SPECIAL_COMMAND_ITEM": this.button.type = "COMMAND"; bSpecialCommandItem = true; break;
  9372.             case "BUTTON": this.button.type = "BUTTON"; break;
  9373.         }
  9374.  
  9375.         if (bSpecialCommandItem)
  9376.             this.button.data = new ToolbarDataParsingXPCOM.dataObjects.Command();
  9377.         else {
  9378.  
  9379.             var xmlData = XML.SelectSingleNode(xmlNode, "DATA");
  9380.             if (xmlData) {
  9381.                 this.button.data = ToolbarDataParsingXPCOM.dataNodeFactory.getDataObject(xmlData);
  9382.                 this.button.type = this.button.data.type;
  9383.             }
  9384.             else
  9385.                 this.button.data = new ToolbarDataParsingXPCOM.dataObjects.Link();
  9386.         }
  9387.  
  9388.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9389.             switch (xmlNode.childNodes[i].tagName) {
  9390.                 case "BUTTON_TEXT":
  9391.                 case "DEFAULT_BUTTON_TEXT": this.button.text = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9392.                 case "BUTTON_TOOLTIP": this.button.tooltip = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9393.                 case "BUTTON_ICON":
  9394.                 case "BUTTON_ICON_URL":
  9395.                     this.button.image = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9396.                     this.button.image = URL.AddHTTPProtocol(this.button.image);
  9397.                     break;
  9398.                 case "BUTTON_LINK":
  9399.                     this.button.data.link = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9400.                     this.button.data.link = URL.LegalizeLinkUrl(this.button.data.link);
  9401.                     break;
  9402.                 case "TARGET": this.button.data.target = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9403.                 case "BUTTON_COMMAND_ID": this.button.data.command = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9404.                 case "DISPLAY_TEXT": this.DisplayText = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9405.                 case "DISPLAY_ICON": this.DisplayIcon = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9406.                 case "USER_ATTRIBUTES":
  9407.                     var XMLUserAttributes = xmlNode.childNodes[i];
  9408.                     var XMLUserAttribute = null;
  9409.                     for (var j = 0; j < XMLUserAttributes.childNodes.length; j++) {
  9410.                         XMLUserAttribute = XMLUserAttributes.childNodes[j];
  9411.                         if (XMLUserAttribute.tagName == "PERMISSION") {
  9412.                             this.Permission = XML.GetXmlNodeValue(XMLUserAttribute);
  9413.                         }
  9414.                         else if (XMLUserAttribute.tagName == "SHOW_IN_CHEVRON") {
  9415.                             this.ShowInChevron = XML.GetXmlNodeValue(XMLUserAttribute);
  9416.                         }
  9417.                     }
  9418.                     break;
  9419.             }
  9420.         }
  9421.     };
  9422.  
  9423.     this.validateTextAndIcon = function() {
  9424.         if (!this.DisplayText)
  9425.             this.DisplayText = this.button.text;
  9426.  
  9427.         if (!this.DisplayIcon)
  9428.             this.DisplayIcon = this.button.image;
  9429.     };
  9430.  
  9431.     this.init();
  9432. };
  9433.  
  9434. ButtonItem.prototype = new BaseToolbarItem();
  9435. function ChatItem(objData) {
  9436.     this.objData = objData;
  9437.     this.button = new Button(objData);
  9438.     
  9439.     //chat specific properties
  9440.     this.serviceUrl = '';
  9441.     this.serviceIntervalMM = 60;
  9442.     this.defaultRoom = null;
  9443.  
  9444.     this.parse = function() {
  9445.         var xmlNode = this.objData.xmlNode;
  9446.         var xmlChildNode = null;
  9447.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9448.             xmlChildNode = xmlNode.childNodes[i];
  9449.             switch (xmlChildNode.tagName) {
  9450.                 case "BUTTON":
  9451.                     this.button.InitWithXML(xmlChildNode);
  9452.                     var xmlUserAttributes = XML.SelectSingleNode(xmlChildNode, "USER_ATTRIBUTES");
  9453.                     this.UniqueCompID = XML.GetSingleNodeValue(xmlChildNode, "UNIQUE_COMP_ID");
  9454.                     if (xmlUserAttributes) {
  9455.                         var XMLUserAttribute = null;
  9456.                         for (var j = 0; j < xmlUserAttributes.childNodes.length; j++) {
  9457.                             XMLUserAttribute = xmlUserAttributes.childNodes[j];
  9458.                             if (XMLUserAttribute.tagName == "PERMISSION")
  9459.                                 this.Permission = XML.GetXmlNodeValue(XMLUserAttribute);
  9460.                             else if (XMLUserAttribute.tagName == "SHOW_IN_CHEVRON")
  9461.                                 this.ShowInChevron = XML.GetXmlNodeValue(XMLUserAttribute);
  9462.                         }
  9463.                     }
  9464.                     break;
  9465.                 case "SERVICE": this.parseService(xmlChildNode); break;
  9466.                 case "DEFAULT_ROOM": this.parseDefaultRoom(xmlChildNode); break;
  9467.             }
  9468.         }
  9469.  
  9470.         //set defaults
  9471.         if (!this.serviceUrl)
  9472.             this.serviceUrl = "http://chat.services.conduit.com/Chat/ChatInfoWebService.asmx/GetChatInfo";
  9473.  
  9474.         if (!this.serviceIntervalMM)
  9475.             this.serviceIntervalMM = 60 * 24;
  9476.  
  9477.         this.DisplayIcon = this.button.image;
  9478.         this.DisplayText = this.button.text;
  9479.     };
  9480.  
  9481.     this.parseService = function(xmlService) {
  9482.         this.serviceUrl = XML.GetSingleNodeValue(xmlService, "URL");
  9483.         this.serviceIntervalMM = XML.GetSingleNodeValueAsInteger(xmlService, "INTERVAL_IN_MM");
  9484.     };
  9485.  
  9486.     this.parseDefaultRoom = function(xmlRoom) {
  9487.         var xmlRoomInfo = XML.SelectSingleNode(xmlRoom, "INFO");
  9488.         this.defaultRoom = new ChatXPCOM.room(xmlRoomInfo);
  9489.     };
  9490.  
  9491.     this.validateUniqueCompID = function() {
  9492.         if (!this.UniqueCompID)
  9493.             this.UniqueCompID = Math.random() * 10;
  9494.     };
  9495.  
  9496.     this.init();
  9497. };
  9498.  
  9499. ChatItem.prototype = new BaseToolbarItem();
  9500. function DynamicMenuItem(objData) {
  9501.     this.objData = objData;
  9502.     this.button = new Button(objData);
  9503.  
  9504.     //default value is regular menu(when the arrow and the button are joined)
  9505.     //MAIN_MENU - the button does an event and the arrow open the menu(devided)
  9506.     this.button.type = "BUTTON_MENU";
  9507.     this.link = "";
  9508.     
  9509.     //the xml of the menu of this dynamic menu
  9510.     this.menuXml = null;
  9511.  
  9512.     //floats menu items
  9513.     this.arrXmlFloatMenuItems = null;
  9514.  
  9515.     this.IsValidMainMenu = false;
  9516.     this.isMainMenu = false;
  9517.  
  9518.     this.parse = function() {
  9519.         var xmlNode = this.objData.xmlNode;
  9520.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9521.             switch (xmlNode.childNodes[i].tagName) {
  9522.                 case "TYPE":
  9523.                     this.button.type = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9524.                     if (this.button.type == "MAIN_MENU") {
  9525.                         this.isMainMenu = true;
  9526.                         this.ShowInChevron = false;
  9527.                     }
  9528.                     break;
  9529.                 case "BUTTON": this.button.InitWithXML(xmlNode.childNodes[i]); break;
  9530.                 case "MENU": this.menuXml = xmlNode.childNodes[i]; break;
  9531.             }
  9532.         }
  9533.     };
  9534.  
  9535.     this.validateTextAndIcon = function() {
  9536.         if (!this.DisplayText)
  9537.             this.DisplayText = this.button.text;
  9538.  
  9539.         if (!this.DisplayIcon)
  9540.             this.DisplayIcon = this.button.image;
  9541.     };
  9542.  
  9543.     this.ValidateMainMenu = function() {
  9544.         if (this.button.text || this.button.icon)
  9545.             this.IsValidMainMenu = true;
  9546.  
  9547.         if (this.isMainMenu)
  9548.             this.isMustHaveComponents = true;
  9549.     };
  9550.  
  9551.     this.init();
  9552.     this.ValidateMainMenu();
  9553. };
  9554.  
  9555. DynamicMenuItem.prototype = new BaseToolbarItem();
  9556. function EMailNotifierItem(objData) {
  9557.     this.objData = objData;
  9558.     this.dynamicMenuItem = null;
  9559.  
  9560.     //default value is 5 minutes
  9561.     this.CheckNewInterval = 5;
  9562.     this.StaredTooltip = '';
  9563.  
  9564.     this.isPersonalComponent = true;
  9565.     this.isPublisher = objData.isPublisher;
  9566.  
  9567.     this.parse = function() {
  9568.         var xmlNode = this.objData.xmlNode;
  9569.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9570.             switch (xmlNode.childNodes[i].tagName) {
  9571.                 case "DYNAMIC_MENU":
  9572.                     var oData = new ToolbarItemData(xmlNode.childNodes[i],
  9573.                                                     ToolbarDataParsingXPCOM.ComponentType.Settings,
  9574.                                                     objData.isPublisher,
  9575.                                                     objData.chromeName,
  9576.                                                     objData.originalCTID,
  9577.                                                     objData.actingCTID);
  9578.                     this.dynamicMenuItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(oData);
  9579.                     this.dynamicMenuItem.DisableUsage = true;
  9580.                     break;
  9581.                 case "CHECK_NEW_EMAILS_INTERVAL": this.CheckNewInterval = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9582.                 case "STARED_TOOLTIP": this.StaredTooltip = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9583.             }
  9584.         }
  9585.     };
  9586.  
  9587.     this.validateTextAndIcon = function() {
  9588.         if (!this.dynamicMenuItem.button.image)
  9589.             this.dynamicMenuItem.button.image = "chrome://" + this.objData.chromeName + "/skin/email.png";
  9590.  
  9591.         if (this.dynamicMenuItem && this.dynamicMenuItem.button.image)
  9592.             this.DisplayIcon = this.dynamicMenuItem.button.image;
  9593.  
  9594.         if (this.dynamicMenuItem && this.dynamicMenuItem.button.text)
  9595.             this.DisplayText = this.dynamicMenuItem.button.text;
  9596.     };
  9597.  
  9598.     this.validateUniqueCompID = function() {
  9599.         if (!this.UniqueCompID)
  9600.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.EMailNotifier;
  9601.     };
  9602.  
  9603.     this.init();
  9604. };
  9605.  
  9606. EMailNotifierItem.prototype = new BaseToolbarItem();
  9607. function ExternalComponentItem(objData) {
  9608.     this.objData = objData;
  9609.     this.type = "";
  9610.     this.interval = 0;
  9611.     this.link = "";
  9612.     this.storeLocally = true;
  9613.     this.cacheMode = "TB_CACHE";
  9614.  
  9615.     this.parse = function() {
  9616.         var xmlNode = this.objData.xmlNode;
  9617.  
  9618.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9619.             switch (xmlNode.childNodes[i].tagName) {
  9620.                 case "TYPE": this.type = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9621.                 case "INTERVAL": this.interval = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9622.                 case "CACHE_MODE": this.cacheMode = XML.GetXmlNodeValue(xmlNode.childNodes[i], "TB_CACHE"); break;
  9623.                 case "EXTERNAL_LINK":
  9624.                     this.link = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9625.                     this.link = URL.AddHTTPProtocol(this.link);
  9626.                     break;
  9627.                 case "DISPLAY_TEXT":
  9628.                     var oDisplayText = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9629.                     if (oDisplayText)
  9630.                         this.DisplayText = oDisplayText;
  9631.                     break;
  9632.                 case "DISPLAY_ICON":
  9633.                     var oDisplayIcon = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9634.                     if (oDisplayIcon)
  9635.                         this.DisplayIcon = oDisplayIcon;
  9636.                     this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  9637.                     break;
  9638.             }
  9639.         }
  9640.     };
  9641.  
  9642.     this.validateTextAndIcon = function() {
  9643.         if (!this.DisplayText)
  9644.             this.DisplayText = "External Menu";
  9645.  
  9646.         if (!this.DisplayIcon)
  9647.             this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/minibrowser.png";
  9648.     };
  9649.  
  9650.     this.init();
  9651. };
  9652.  
  9653. ExternalComponentItem.prototype = new BaseToolbarItem();
  9654. function FacebookItem(objData) {
  9655.     this.objData = objData;
  9656.  
  9657.     this.serviceUrl = "";
  9658.     this.serviceIntervalSec = 0;
  9659.     this.fbIconUrl = "";
  9660.     
  9661.     this.facebookAcceptAllCheck = null;
  9662.     this.facebookFriendReqCheck = null;
  9663.     this.facebookInboxCheck = null;
  9664.     this.facebookGroupsCheck = null;
  9665.     this.facebookEventsCheck = null;
  9666.     this.facebookNewFeedCheck = null;
  9667.  
  9668.     this.isPersonalComponent = true;
  9669.     this.isPublisher = objData.isPublisher;
  9670.  
  9671.     this.parse = function() {
  9672.         var xmlNode = this.objData.xmlNode;
  9673.         this.serviceUrl = XML.GetSingleNodeValue(xmlNode, "FB_SERVICE_URL");
  9674.         this.fbIconUrl = XML.GetSingleNodeValue(xmlNode, "FB_ICON_URL");
  9675.         this.serviceIntervalSec = XML.GetSingleNodeValueAsInteger(xmlNode, "FB_SERVICE_INTERVAL_SEC", 24 * 7 * 60 * 60);
  9676.         var xmlAlerts = XML.SelectSingleNode(xmlNode, "ALERTS");
  9677.         this.parseAlerts(xmlAlerts);
  9678.     };
  9679.  
  9680.     this.parseAlerts = function(xmlNode) {
  9681.         this.facebookAcceptAllCheck = XML.GetSingleNodeValueAsBoolean(xmlNode, "ACCEPT_ALL", null);
  9682.         this.facebookFriendReqCheck = XML.GetSingleNodeValueAsBoolean(xmlNode, "FRIEND_REQUESTS", null);
  9683.         this.facebookInboxCheck = XML.GetSingleNodeValueAsBoolean(xmlNode, "INBOX", null);
  9684.         this.facebookGroupsCheck = XML.GetSingleNodeValueAsBoolean(xmlNode, "GROUPS", null);
  9685.         this.facebookEventsCheck = XML.GetSingleNodeValueAsBoolean(xmlNode, "EVENTS", null);
  9686.         this.facebookNewFeedCheck = XML.GetSingleNodeValueAsBoolean(xmlNode, "NEWS_FEED", null);
  9687.     };
  9688.     
  9689.     this.validateUniqueCompID = function() {
  9690.         if (!this.UniqueCompID)
  9691.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.Facebook;
  9692.     };
  9693.  
  9694.     this.init();
  9695. };
  9696.  
  9697. FacebookItem.prototype = new BaseToolbarItem();
  9698.  
  9699.  
  9700. function FeedItem(objData) {
  9701.     this.objData = objData;
  9702.     this.Title = "";
  9703.     this.FeedURL = "";
  9704.     this.IconNormalURL = "";
  9705.     this.Interval = 0;
  9706.  
  9707.     this.LiveMode = false;
  9708.     this.Comments = "";
  9709.     this.Podcast = false;
  9710.  
  9711.     this.parse = function() {
  9712.         var xmlNode = this.objData.xmlNode;
  9713.  
  9714.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9715.             switch (xmlNode.childNodes[i].tagName) {
  9716.                 case "TITLE": this.Title = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9717.                 case "LINK":
  9718.                     this.FeedURL = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9719.                     this.FeedURL = XML.FromLegalXml(this.FeedURL);
  9720.                     break;
  9721.                 case "INTERVAL": this.Interval = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9722.                 case "PODCAST": this.Podcast = XML.GetBooleanXmlNodeValue(xmlNode.childNodes[i]); break;
  9723.                 case "ICON_NORMAL_URL":
  9724.                     this.IconNormalURL = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9725.                     this.IconNormalURL = URL.AddHTTPProtocol(this.IconNormalURL);
  9726.                     break;
  9727.                 case "DISPLAY_TEXT": this.DisplayText = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9728.                 case "DISPLAY_ICON":
  9729.                     this.DisplayIcon = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  9730.                     this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  9731.                     break;
  9732.                 case "LIVE_MODE": this.LiveMode = XML.GetBooleanXmlNodeValue(xmlNode.childNodes[i]); break;
  9733.                 case "COMMENTS_LINK": this.Comments = XML.GetXmlNodeValue(xmlNode.childNodes[i]); break;
  9734.             }
  9735.         }
  9736.     };
  9737.  
  9738.     this.validateTextAndIcon = function() {
  9739.         if (!this.DisplayText)
  9740.             this.DisplayText = this.Title;
  9741.  
  9742.         if (!this.DisplayIcon)
  9743.             this.DisplayIcon = this.IconNormalURL;
  9744.     };
  9745.  
  9746.     this.init();
  9747. };
  9748.  
  9749. FeedItem.prototype = new BaseToolbarItem();
  9750. function HighlighterItem(objData) {
  9751.     this.objData = objData;
  9752.     
  9753.     this.strTooltip = "";
  9754.  
  9755.     this.DisplayText = "Highlighter";
  9756.     this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/highlighter.png";
  9757.  
  9758.     this.parse = function() {
  9759.         var xmlNode = this.objData.xmlNode;
  9760.         this.strTooltip = XML.GetSingleNodeValue(xmlNode, "HIGHLIGHT_TOOLTIP");
  9761.     };
  9762.  
  9763.     this.validateUniqueCompID = function() {
  9764.         if (!this.UniqueCompID)
  9765.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.Highlighter;
  9766.     };
  9767.  
  9768.     this.init();
  9769. };
  9770.  
  9771. HighlighterItem.prototype = new BaseToolbarItem();
  9772. function LabelItem(objData) {
  9773.     this.objData = objData;
  9774.     this.button = new Button(objData);
  9775.  
  9776.     this.parse = function() {
  9777.         var xmlNode = this.objData.xmlNode;
  9778.         //set the type
  9779.         this.button.type = "LABEL";
  9780.         var xmlButton = XML.SelectSingleNode(xmlNode, "BUTTON");
  9781.         if(xmlButton)
  9782.         this.button.InitWithXML(xmlButton);
  9783.         
  9784.         this.DisplayText = XML.GetSingleNodeValue(xmlNode, "DISPLAY_TEXT");
  9785.         this.DisplayIcon = XML.GetSingleNodeValue(xmlNode, "DISPLAY_ICON");
  9786.         this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  9787.     };
  9788.  
  9789.     this.validateTextAndIcon = function() {
  9790.         if (!this.DisplayText && !this.DisplayIcon) {
  9791.             this.DisplayText = this.button.text;
  9792.             this.DisplayIcon = this.button.image;
  9793.         }
  9794.     };
  9795.  
  9796.     this.init();
  9797. };
  9798.  
  9799. LabelItem.prototype = new BaseToolbarItem();
  9800. function MultiCommunityItem(objData) {
  9801.     this.objData = objData;
  9802.     this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.MultiCommunity;
  9803.     this.CompType = ToolbarDataParsingXPCOM.ComponentType.Settings;
  9804.  
  9805.     this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/mc_add_inactive.png";
  9806.     this.Tooltip = "Community Toolbar Detected";
  9807.  
  9808.     this.Permission = ToolbarDataParsingXPCOM.Editable.NONE;
  9809.  
  9810.     this.MenuItem1Icon = "chrome://" + this.objData.chromeName + "/skin/mc_add_inactive.png";
  9811.     this.MenuItem2Icon = "chrome://" + this.objData.chromeName + "/skin/mc_search.png";
  9812.     this.MenuItem3Icon = "chrome://" + this.objData.chromeName + "/skin/mc_options.png";
  9813.  
  9814.     this.isMustHaveComponents = true;
  9815.     this.ShowInChevron = false;
  9816.  
  9817.     this.parseUserAttributes = function() { };
  9818.     this.validateUniqueCompID = function() { };
  9819.  
  9820.     this.parseCommonData = function() { };
  9821.     this.parseUserAttributes = function() { };
  9822.     
  9823.     this.init();
  9824. };
  9825.  
  9826. MultiCommunityItem.prototype = new BaseToolbarItem();
  9827. function MultiFeedItem(objData) {
  9828.     this.objData = objData;
  9829.     this.FeedItems = new Array();
  9830.     this.MultiFeedButton = null;
  9831.  
  9832.     this.parse = function() {
  9833.         var XMLNode = this.objData.xmlNode;
  9834.         var XMLNodeChild = null;
  9835.         var XMLFeedItemNode = null;
  9836.  
  9837.         for (var i = 0; i < XMLNode.childNodes.length; i++) {
  9838.             XMLNodeChild = XMLNode.childNodes[i];
  9839.             switch (XMLNodeChild.tagName) {
  9840.                 case "LIST_OF_RSS_FEEDS":
  9841.                     for (var j = 0; j < XMLNodeChild.childNodes.length; j++) {
  9842.                         XMLFeedItemNode = XMLNodeChild.childNodes[j];
  9843.                         if (XMLFeedItemNode.tagName == 'RSS_FEED_ITEM') {
  9844.                             var oData = new ToolbarItemData(XMLFeedItemNode,
  9845.                                                     ToolbarDataParsingXPCOM.ComponentType.Settings,
  9846.                                                     objData.isPublisher,
  9847.                                                     objData.chromeName,
  9848.                                                     objData.originalCTID,
  9849.                                                     objData.actingCTID);
  9850.                             this.FeedItems.push(ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(oData));
  9851.                         }
  9852.                     }
  9853.                     break;
  9854.                 case "BUTTON": this.MultiFeedButton = new MultiFeedButtonItem(XMLNodeChild); break;
  9855.                 case "DISPLAY_TEXT": this.DisplayText = XML.GetXmlNodeValue(XMLNodeChild); break;
  9856.                 case "DISPLAY_ICON":
  9857.                     this.DisplayIcon = XML.GetXmlNodeValue(XMLNodeChild);
  9858.                     this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  9859.                     break;
  9860.             }
  9861.         }
  9862.     };
  9863.  
  9864.     this.validateTextAndIcon = function() {
  9865.         if (!this.DisplayText)
  9866.             this.DisplayText = this.MultiFeedButton.DeafultButtonText;
  9867.  
  9868.         if (!this.DisplayIcon)
  9869.             this.DisplayIcon = this.MultiFeedButton.IconNormalURL;
  9870.     };
  9871.  
  9872.     this.init();
  9873. };
  9874.  
  9875. MultiFeedItem.prototype = new BaseToolbarItem();
  9876. //object represent multi feed object
  9877. function MultiFeedButtonItem(XMLNode) {
  9878.     this.DeafultButtonText = "";
  9879.     this.IconNormalURL = "";
  9880.     this.ButtonTooltip = "";
  9881.  
  9882.     this.Create = function(XMLNode) {
  9883.         var XMLNodeChild = null;
  9884.         for (var i = 0; i < XMLNode.childNodes.length; i++) {
  9885.             XMLNodeChild = XMLNode.childNodes[i];
  9886.             if (XMLNodeChild.tagName == 'DEFAULT_BUTTON_TEXT')
  9887.                 this.DeafultButtonText = XML.GetXmlNodeValue(XMLNodeChild);
  9888.             else if (XMLNodeChild.tagName == 'ICON_NORMAL_URL')
  9889.                 this.IconNormalURL = XML.GetXmlNodeValue(XMLNodeChild);
  9890.             else if (XMLNodeChild.tagName == 'BUTTON_TOOLTIP')
  9891.                 this.ButtonTooltip = XML.GetXmlNodeValue(XMLNodeChild);
  9892.         }
  9893.     };
  9894.  
  9895.     this.Create(XMLNode);
  9896. };
  9897. function MyStuffButtonItem(objData) {
  9898.     this.objData = objData;
  9899.     this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.MyStuffAddButton;
  9900.     this.CompType = ToolbarDataParsingXPCOM.ComponentType.MyStuff;
  9901.  
  9902.     this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/myStuff/add.png";
  9903.     this.DisplayText = "";
  9904.  
  9905.     this.Permission = ToolbarDataParsingXPCOM.Editable.NONE;
  9906.     this.isMustHaveComponents = true;
  9907.  
  9908.     this.parseUserAttributes = function() { };
  9909.     this.validateUniqueCompID = function() { };
  9910.  
  9911.     this.parseCommonData = function() { };
  9912.     this.parseUserAttributes = function() { };
  9913.  
  9914.     this.init();
  9915. };
  9916.  
  9917. MyStuffButtonItem.prototype = new BaseToolbarItem();
  9918.  
  9919. function MyStuffWithOptionsButtonItem(objData) {
  9920.     this.objData = objData;
  9921.     this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.MyStuffOptionsButton;
  9922.     this.CompType = ToolbarDataParsingXPCOM.ComponentType.MyStuff;
  9923.  
  9924.     this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/myStuff/add.png";
  9925.     this.DisplayText = "";
  9926.     this.optionsIcon = "chrome://" + this.objData.chromeName + "/skin/myStuff/options.png";
  9927.  
  9928.     this.Permission = ToolbarDataParsingXPCOM.Editable.NONE;
  9929.     this.isMustHaveComponents = true;
  9930.  
  9931.     this.parseUserAttributes = function() { };
  9932.     this.validateUniqueCompID = function() { };
  9933.  
  9934.     this.parseCommonData = function() { };
  9935.     this.parseUserAttributes = function() { };
  9936.  
  9937.     this.init();
  9938. };
  9939.  
  9940. MyStuffWithOptionsButtonItem.prototype = new BaseToolbarItem();
  9941.  
  9942. function PrivacyItem(objData) {
  9943.     this.objData = objData;
  9944.     
  9945.     this.dynamicMenuItem = null;
  9946.     this.isPersonalComponent = true;
  9947.     var buttonIconUrl = '';
  9948.     var blockIcon = '';
  9949.  
  9950.     this.parse = function() {
  9951.         var xmlNode = this.objData.xmlNode;
  9952.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  9953.             if (xmlNode.childNodes[i].tagName == "DYNAMIC_MENU") {
  9954.                 var oData = new ToolbarItemData(xmlNode.childNodes[i],
  9955.                                                     ToolbarDataParsingXPCOM.ComponentType.Settings,
  9956.                                                     objData.isPublisher,
  9957.                                                     objData.chromeName,
  9958.                                                     objData.originalCTID,
  9959.                                                     objData.actingCTID);
  9960.                 this.dynamicMenuItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(oData);
  9961.  
  9962.                 //private case of firefox - change the defaults:
  9963.                 this.dynamicMenuItem.button.text = "Privacy";
  9964.                 buttonIconUrl = this.dynamicMenuItem.button.image;
  9965.                 this.dynamicMenuItem.button.tooltip = "";
  9966.             }
  9967.             else if (xmlNode.childNodes[i].tagName == "POPUP_BLOCKER_BUTTON") {
  9968.                 var xmlSubNode = xmlNode.childNodes[i];
  9969.                 for (var j = 0; j < xmlSubNode.childNodes.length; j++) {
  9970.                     if (xmlSubNode.childNodes[j].tagName == "BUTTON_ICON_BLOCK_POPUPS") {
  9971.                         blockIcon = XML.GetXmlNodeValue(xmlSubNode.childNodes[j]);
  9972.                     }
  9973.                 }
  9974.             }
  9975.         }
  9976.  
  9977.         if (blockIcon) {
  9978.             this.dynamicMenuItem.button.image = blockIcon;
  9979.             this.DisplayIcon = blockIcon;
  9980.         }
  9981.         else if (buttonIconUrl) {
  9982.             this.dynamicMenuItem.button.image = buttonIconUrl;
  9983.             this.DisplayIcon = buttonIconUrl;
  9984.         }
  9985.         else {
  9986.             this.dynamicMenuItem.button.image = "chrome://" + this.objData.chromeName + "/skin/block.png";
  9987.             this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/block.png";
  9988.         }
  9989.     };
  9990.  
  9991.     this.validateUniqueCompID = function() {
  9992.         if (!this.UniqueCompID)
  9993.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.Privacy;
  9994.     };
  9995.  
  9996.     this.init();
  9997. };
  9998.  
  9999. PrivacyItem.prototype = new BaseToolbarItem();
  10000. function RadioItem(objData) {
  10001.     this.objData = objData;
  10002.     this.CompType = ToolbarDataParsingXPCOM.ComponentType.Settings;
  10003.  
  10004.     this.PredefinedListInterval = 0;
  10005.     this.PodcastInterval = 0;
  10006.  
  10007.     this.RadioServerURL = '';
  10008.     this.EnableIPStations = true;
  10009.  
  10010.     this.xmlSkins = null;
  10011.     this.Skins = null;
  10012.     this.isPersonalComponent = true;
  10013.     
  10014.     this.parse = function() {
  10015.         var xmlNode = this.objData.xmlNode;
  10016.         this.PredefinedListInterval = XML.GetSingleNodeValueAsInteger(xmlNode, "PREDEFINED_LIST_INTERVAL");
  10017.         this.PodcastInterval = XML.GetSingleNodeValueAsInteger(xmlNode, "PODCAST_INTERVAL");
  10018.         this.RadioServerURL = XML.GetSingleNodeValue(xmlNode, "RADIO_SERVER_URL");
  10019.         this.DisplayText = XML.GetSingleNodeValue(xmlNode, "DISPLAY_TEXT");
  10020.         this.DisplayIcon = URL.AddHTTPProtocol(XML.GetSingleNodeValue(xmlNode, "DISPLAY_ICON"));
  10021.         this.EnableIPStations = XML.GetSingleNodeValueAsBoolean(xmlNode, "ENABLE_IP_STATIONS");
  10022.         this.xmlSkins = XML.SelectSingleNode(xmlNode, "LIST_OF_SKINS");
  10023.     };
  10024.  
  10025.     this.validateUniqueCompID = function() {
  10026.         if (!this.UniqueCompID)
  10027.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.Radio;
  10028.     };
  10029.     
  10030.     this.validateTextAndIcon = function() {
  10031.         if (!this.DisplayText)
  10032.             this.DisplayText = "Radio Player";
  10033.  
  10034.         if (!this.DisplayIcon)
  10035.             this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/radio/RadioPlayChev.ico";
  10036.     };
  10037.  
  10038.     this.init();
  10039. };
  10040.  
  10041. RadioItem.prototype = new BaseToolbarItem();
  10042. function SearchBoxItem(objData) {
  10043.     this.objData = objData;
  10044.     var CAN_CHANGE_DEFAULT = "CAN_CHANGE_DEFAULT";
  10045.     //the xml of all the searches
  10046.     this.searchEnginesXml = null;
  10047.     this.searchSuggestsXml = null;
  10048.     this.canChangeDefault = true; //boolean
  10049.     this.strBgColor = "";
  10050.     this.CompType = ToolbarDataParsingXPCOM.ComponentType.Settings;
  10051.     this.Permission = ToolbarDataParsingXPCOM.Editable.NONE;
  10052.     this.backToDefault; //boolean
  10053.     this.searchHookUrl = "";
  10054.     this.DisplayIconPrimary = "";
  10055.     this.mirrorActivateIconOnRTL = true;
  10056.     this.ShowInChevron = false;
  10057.  
  10058.     this.isMustHaveComponents = true;
  10059.  
  10060.     this.parseUserAttributes = function() {
  10061.         var xmlUserAttributes = XML.SelectSingleNode(this.objData.xmlNode, "USER_ATTRIBUTES");
  10062.         if (!xmlUserAttributes) return;
  10063.  
  10064.         /* var showInChevron = XML.GetSingleNodeValueAsBoolean(xmlUserAttributes, "SHOW_IN_CHEVRON", null);
  10065.         if (showInChevron != null) this.ShowInChevron = showInChevron;*/
  10066.     };
  10067.  
  10068.     this.parse = function() {
  10069.         var xmlNode = this.objData.xmlNode;
  10070.         this.searchEnginesXml = XML.SelectSingleNode(xmlNode, "LIST_OF_SEARCH_ENGINES");
  10071.         this.searchSuggestsXml = XML.SelectSingleNode(xmlNode, "LIST_OF_SUGGEST_SEARCH_ENGINES");
  10072.         var canChangeDefault = XML.GetSingleNodeValue(xmlNode, "TYPE", CAN_CHANGE_DEFAULT);
  10073.         this.canChangeDefault = canChangeDefault == CAN_CHANGE_DEFAULT;
  10074.         this.strBgColor = XML.GetSingleNodeValue(xmlNode, "BG_COLOR");
  10075.         this.backToDefault = XML.GetSingleNodeValueAsBoolean(xmlNode, "BACK_TO_DEFAULT", true);
  10076.         this.DisplayIcon = XML.GetSingleNodeValue(xmlNode, "ICON_SEARCH_ACTIVATE_URL");
  10077.         this.DisplayIconPrimary = XML.GetSingleNodeValue(xmlNode, "ICON_SEARCH_ACTIVATE_URL_PRIMARY", "");
  10078.         this.mirrorActivateIconOnRTL = XML.GetSingleNodeValueAsBoolean(xmlNode, "ICON_SEARCH_ACTIVATE_IS_MIRROR_ON_RTL", true);
  10079.         this.DisplayText = XML.GetSingleNodeValue(xmlNode, "SEARCH_ACTIVATE_CAPTION");
  10080.         this.searchHookUrl = XML.GetSingleNodeValue(xmlNode, "SEARCH_HOOK_URL");
  10081.     };
  10082.  
  10083.     this.validateUniqueCompID = function() {
  10084.         if (!this.UniqueCompID)
  10085.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.SearchBox;
  10086.     };
  10087.  
  10088.     this.validateTextAndIcon = function() {
  10089.         this.DisplayIcon = (this.DisplayIconPrimary) ? this.DisplayIconPrimary : this.DisplayIcon;
  10090.  
  10091.         if (!this.DisplayIcon)
  10092.             this.DisplayIcon = "chrome://" + this.objData.chromeName + "/skin/go_btn.gif";
  10093.  
  10094.     };
  10095.  
  10096.     this.init();
  10097. };
  10098.  
  10099. SearchBoxItem.prototype = new BaseToolbarItem();
  10100. function SeparatorItem(objData) {
  10101.     this.objData = objData;
  10102.     
  10103.     this.UniqueCompID = '';
  10104.     this.CompType = objData.compType;
  10105.  
  10106.     this.DisplayText = "Separator";
  10107.     this.DisplayIcon = "chrome://" + objData.chromeName + "/skin/separator.png";
  10108.  
  10109.     this.init();
  10110. };
  10111.  
  10112. SeparatorItem.prototype = new BaseToolbarItem();
  10113. function ToggleItem(objData) {
  10114.     this.objData = objData;
  10115.     
  10116.     var buttonIconUrl = '';
  10117.     var blockIcon = '';
  10118.  
  10119.     this.buttonOn = new Button(objData);
  10120.     this.buttonOff = new Button(objData);
  10121.     this.button = null;
  10122.  
  10123.     this.scriptOn = '';
  10124.     this.scriptOff = '';
  10125.     this.scriptUrl = '';
  10126.     this.mode = '';
  10127.  
  10128.     this.parse = function() {
  10129.         var xmlNode = this.objData.xmlNode;
  10130.         var xmlMode = null;
  10131.         var i, j;
  10132.  
  10133.         for (i = 0; i < xmlNode.childNodes.length; i++) {
  10134.             if (xmlNode.childNodes[i].tagName == "DISPLAY_TEXT")
  10135.                 this.DisplayText = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  10136.             else if (xmlNode.childNodes[i].tagName == "DISPLAY_ICON") {
  10137.                 this.DisplayIcon = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  10138.                 this.DisplayIcon = URL.AddHTTPProtocol(this.DisplayIcon);
  10139.             }
  10140.             else if (xmlNode.childNodes[i].tagName == "MODE_ON") {
  10141.                 xmlMode = xmlNode.childNodes[i];
  10142.                 for (j = 0; j < xmlMode.childNodes.length; j++) {
  10143.                     if (xmlMode.childNodes[j].tagName == "BUTTON")
  10144.                         this.buttonOn.InitWithXML(xmlMode.childNodes[j]);
  10145.                     else if (xmlMode.childNodes[j].tagName == "FUNCTION")
  10146.                         this.scriptOn = XML.GetXmlNodeValue(xmlMode.childNodes[j]);
  10147.                 }
  10148.             }
  10149.             else if (xmlNode.childNodes[i].tagName == "MODE_OFF") {
  10150.                 xmlMode = xmlNode.childNodes[i];
  10151.                 for (j = 0; j < xmlMode.childNodes.length; j++) {
  10152.                     if (xmlMode.childNodes[j].tagName == "BUTTON")
  10153.                         this.buttonOff.InitWithXML(xmlMode.childNodes[j]);
  10154.                     else if (xmlMode.childNodes[j].tagName == "FUNCTION")
  10155.                         this.scriptOff = XML.GetXmlNodeValue(xmlMode.childNodes[j]);
  10156.                 }
  10157.             }
  10158.             else if (xmlNode.childNodes[i].tagName == "SCRIPT_URL")
  10159.                 this.scriptUrl = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  10160.             else if (xmlNode.childNodes[i].tagName == "MODE")
  10161.                 this.mode = XML.GetXmlNodeValue(xmlNode.childNodes[i]);
  10162.         }
  10163.     };
  10164.  
  10165.     this.validateTextAndIcon = function() {
  10166.         if (!this.buttonOn.text && !this.buttonOn.image) {
  10167.             this.buttonOn.text = this.buttonOff.text;
  10168.             this.buttonOn.image = this.buttonOff.image;
  10169.         }
  10170.  
  10171.         if (!this.DisplayText && !this.DisplayIcon) {
  10172.             this.DisplayText = this.buttonOff.text;
  10173.             this.DisplayIcon = this.buttonOff.image;
  10174.         }
  10175.  
  10176.         if (!this.mode)
  10177.             this.mode = "TEMPORARY";
  10178.     };
  10179.  
  10180.     this.init();
  10181. };
  10182.  
  10183. ToggleItem.prototype = new BaseToolbarItem();
  10184. function TwitterItem(objData) {
  10185.     this.objData = objData;
  10186.     this.button = new Button(objData);
  10187.     this.generalUserInfo = null; // objGeneralUserInfo
  10188.     this.arrFollowedUsers = null;  //array of objUserInfo
  10189.  
  10190.     this.parse = function() {
  10191.         var xmlNode = this.objData.xmlNode;
  10192.         var xmlButton = XML.SelectSingleNode(xmlNode, "BUTTON");
  10193.         if (xmlButton)
  10194.             this.button.InitWithXML(xmlButton);
  10195.  
  10196.         //set general user info
  10197.         var xmlGeneralUserInfo = XML.SelectSingleNode(xmlNode, "GENERAL_USER_INFO");
  10198.         if (xmlGeneralUserInfo)
  10199.             this.generalUserInfo = new TwitterGeneralUserInfo(xmlGeneralUserInfo);
  10200.  
  10201.         //set followed users
  10202.         var xmlFollowedUsers = XML.SelectSingleNode(xmlNode, "FOLLOWED_USERS");
  10203.         if (xmlFollowedUsers) {
  10204.             var baseUserPageUrl = (this.generalUserInfo && this.generalUserInfo.personalPageBaseUrl) ?
  10205.                 this.generalUserInfo.personalPageBaseUrl : "http://twitter.com/@@SCREEN_NAME@@";
  10206.             var baseRssUrl = (this.generalUserInfo && this.generalUserInfo.rssBaseUrl) ?
  10207.                 this.generalUserInfo.rssBaseUrl : "http://twitter.com/statuses/user_timeline/@@ID@@.rss";
  10208.  
  10209.             var iRssInerval = (this.generalUserInfo && this.generalUserInfo.rssInterval) ?
  10210.                 this.generalUserInfo.rssInterval : 25;
  10211.                 
  10212.             this.arrFollowedUsers = new Array();
  10213.             var xmlFollowedUser = null;
  10214.             var objFollowedUser = null;
  10215.             for (var j = 0; j < xmlFollowedUsers.childNodes.length; j++) {
  10216.                 xmlFollowedUser = xmlFollowedUsers.childNodes[j];
  10217.                 if (xmlFollowedUser && xmlFollowedUser.tagName && xmlFollowedUser.tagName == "USER") {
  10218.                     objFollowedUser = new TwitterUserInfo(xmlFollowedUser, baseUserPageUrl, baseRssUrl, iRssInerval);
  10219.                     this.arrFollowedUsers.push(objFollowedUser);
  10220.                 }
  10221.             }
  10222.         }
  10223.     };
  10224.  
  10225.     this.validateTextAndIcon = function() {
  10226.         if (!this.DisplayText && !this.DisplayIcon) {
  10227.             this.DisplayText = this.button.text;
  10228.             this.DisplayIcon = this.button.image;
  10229.         }
  10230.     };
  10231.  
  10232.     this.init();
  10233. };
  10234.  
  10235. TwitterItem.prototype = new BaseToolbarItem();
  10236. function WeatherItem(objData) {
  10237.     this.objData = objData;
  10238.     
  10239.     var XMLNode = objData.xmlNode;
  10240.     this.Interval = '';
  10241.     this.Button = new Button(objData);
  10242.     this.ServerURL = '';
  10243.     this.WebSearchURL = '';
  10244.     
  10245.     this.isPersonalComponent = true;
  10246.  
  10247.     this.parse = function() {
  10248.         var xmlNode = this.objData.xmlNode;
  10249.         var XMLNodeChild = null;
  10250.  
  10251.         for (var i = 0; i < xmlNode.childNodes.length; i++) {
  10252.             XMLNodeChild = xmlNode.childNodes[i];
  10253.             if (XMLNodeChild.tagName == "INTERVAL")
  10254.                 this.Interval = XML.GetXmlNodeValue(XMLNodeChild);
  10255.             else if (XMLNodeChild.tagName == "BUTTON")
  10256.                 this.Button.InitWithXML(XMLNodeChild);
  10257.             else if (XMLNodeChild.tagName == "SERVER_URL")
  10258.                 this.ServerURL = XML.GetXmlNodeValue(XMLNodeChild);
  10259.             else if (XMLNodeChild.tagName == "SEARCH_SERVER_URL")
  10260.                 this.WebSearchURL = XML.GetXmlNodeValue(XMLNodeChild);
  10261.             else if (XMLNodeChild.tagName == "UNIQUE_COMP_ID")
  10262.                 this.UniqueCompID = XML.GetXmlNodeValue(XMLNodeChild);
  10263.         }
  10264.     };
  10265.  
  10266.     this.validateUniqueCompID = function() {
  10267.         if (!this.UniqueCompID)
  10268.             this.UniqueCompID = ToolbarDataParsingXPCOM.ComponentsID.Weather;
  10269.     };
  10270.  
  10271.     this.validateTextAndIcon = function() {
  10272.         if (this.Button && this.Button.image)
  10273.             this.DisplayIcon = this.Button.image;
  10274.  
  10275.         if (this.Button && this.Button.text)
  10276.             this.DisplayText = this.Button.text;
  10277.     };
  10278.  
  10279.     this.init();
  10280. };
  10281.  
  10282. WeatherItem.prototype = new BaseToolbarItem();function ToolbarSkin(xmlSkin, objStyle, blinkBGColor, chromeName) {
  10283.     this.isInit = false;
  10284.     var getValue = function() {
  10285.         for (var i = 0; i < arguments.length; i++)
  10286.             if (arguments[i]) return arguments[i];
  10287.     };
  10288.  
  10289.     this.__defineGetter__("splitterImageUrl", function() { return getValue(_splitterImageUrl.val, null, _splitterImageUrl.def); });
  10290.     this.__defineGetter__("separatorImageUrl", function() { return getValue(_separatorImageUrl.val, null, _separatorImageUrl.def); });
  10291.     this.__defineGetter__("dropDownArrowImageUrl", function() { return getValue(_dropDownArrowImageUrl.val, null, _dropDownArrowImageUrl.def); });
  10292.     this.__defineGetter__("fontColor", function() { return getValue(_fontColor.val, objStyle.color, _fontColor.def); });
  10293.     this.__defineGetter__("chevronImageUrl", function() { return getValue(_chevronImageUrl.val, null, _chevronImageUrl.def); });
  10294.     this.__defineGetter__("backgroundImageUrl", function() { return getValue(_background_imageUrl.val, null, _background_imageUrl.def); });
  10295.     this.__defineGetter__("backgroundColor", function() { return getValue(_background_color.val, null, _background_color.def); });
  10296.     this.__defineGetter__("highlighterActiveImageUrl", function() { return getValue(_highlighter_activeImageUrl.val, null, _highlighter_activeImageUrl.def); });
  10297.     this.__defineGetter__("highlighterInactiveImageUrl", function() { return getValue(_highlighter_inactiveImageUrl.val, null, _highlighter_inactiveImageUrl.def); });
  10298.     this.__defineGetter__("myStuffImageUrl", function() { return getValue(_myStuff_imageUrl.val, null, _myStuff_imageUrl.def); });
  10299.     this.__defineGetter__("myStuffBlinkColor", function() { return getValue(_myStuff_blinkColor.val, blinkBGColor, _myStuff_blinkColor.def); });
  10300.     this.__defineGetter__("groupActiveImageUrl", function() { return getValue(_group_activeImageUrl.val, null, _group_activeImageUrl.def); });
  10301.     this.__defineGetter__("groupInactiveImageUrl", function() { return getValue(_group_inactiveImageUrl.val, null, _group_inactiveImageUrl.def); });
  10302.     this.__defineGetter__("groupFlashingIconUrl", function() { return getValue(_group_flashingIconUrl.val, null, _group_flashingIconUrl.def); });
  10303.     
  10304.     var _splitterImageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/splitter.ico', chromeName) };
  10305.     var _separatorImageUrl = { "val": null, "def": null };
  10306.     var _dropDownArrowImageUrl = { "val": null, "def": null };
  10307.     var _fontColor = { "val": null, "def": null };
  10308.     var _chevronImageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/chevron.png', chromeName) };
  10309.     var _background_imageUrl = { "val": null, "def": null };
  10310.     var _background_color = { "val": null, "def": null };
  10311.     var _highlighter_activeImageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/highlighter.png', chromeName) };
  10312.     var _highlighter_inactiveImageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/highlighterDisabled.png', chromeName) };
  10313.     var _myStuff_imageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/myStuff/add.png', chromeName) };
  10314.     var _myStuff_blinkColor = { "val": null, "def": "rgb(255, 214, 89)" };
  10315.     var _group_activeImageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/mc_add_active.png', chromeName) };
  10316.     var _group_inactiveImageUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/mc_add_inactive.png', chromeName) };
  10317.     var _group_flashingIconUrl = { "val": null, "def": stringFormat('chrome://{0}/skin/mc_add_flashing.gif', chromeName) };
  10318.  
  10319.     this._init = function() {
  10320.         this.isInit = true;
  10321.         var xmlNode = null;
  10322.  
  10323.         _splitterImageUrl.val = XML.GetSingleNodeValue(xmlSkin, "SPLITTER_IMAGE_URL", null);
  10324.         _separatorImageUrl.val = XML.GetSingleNodeValue(xmlSkin, "SEPARATOR_IMAGE_URL", null);
  10325.         _dropDownArrowImageUrl.val = XML.GetSingleNodeValue(xmlSkin, "DROP_DOWN_ARROW_IMAGE_URL", null);
  10326.         _chevronImageUrl.val = XML.GetSingleNodeValue(xmlSkin, "CHEVRON_IMAGE_URL", null);
  10327.         _fontColor.val = XML.GetSingleNodeValue(xmlSkin, "FONT_COLOR", null);
  10328.  
  10329.         xmlNode = XML.SelectSingleNode(xmlSkin, "BACKGROUND");
  10330.         if (xmlNode) {
  10331.             _background_imageUrl.val = XML.GetSingleNodeValue(xmlNode, "IMAGE_URL", null);
  10332.             _background_color.val = XML.GetSingleNodeValue(xmlNode, "COLOR", null);
  10333.         }
  10334.  
  10335.         xmlNode = XML.SelectSingleNode(xmlSkin, "HIGHLIGHTER");
  10336.         if (xmlNode) {
  10337.             _highlighter_activeImageUrl.val = XML.GetSingleNodeValue(xmlNode, "ACTIVE_IMAGE_URL", null);
  10338.             _highlighter_inactiveImageUrl.val = XML.GetSingleNodeValue(xmlNode, "INACTIVE_IMAGE_URL", null);
  10339.         }
  10340.         
  10341.         xmlNode = XML.SelectSingleNode(xmlSkin, "MY_STUFF");
  10342.         if (xmlNode) {
  10343.             _myStuff_imageUrl.val = XML.GetSingleNodeValue(xmlNode, "IMAGE_URL", null);
  10344.             _myStuff_blinkColor.val = XML.GetSingleNodeValue(xmlNode, "BLINK_COLOR", null);
  10345.         }
  10346.  
  10347.         xmlNode = XML.SelectSingleNode(xmlSkin, "GROUP");
  10348.         if (xmlNode) {
  10349.             _group_activeImageUrl.val = XML.GetSingleNodeValue(xmlNode, "ACTIVE_IMAGE_URL", null);
  10350.             _group_inactiveImageUrl.val = XML.GetSingleNodeValue(xmlNode, "INACTIVE_IMAGE_URL", null);
  10351.             _group_flashingIconUrl.val = XML.GetSingleNodeValue(xmlNode, "FLASHING_IMAGE_URL", null);
  10352.         }
  10353.     };
  10354.  
  10355.     this.getStyleString = function() {
  10356.         var styleString = "";
  10357.         if (this.fontColor)
  10358.             styleString += "color:" + this.fontColor + ";";
  10359.         return objStyle.getStyleStringWithoutColor() + styleString;
  10360.     };
  10361.  
  10362.     if (xmlSkin)
  10363.         this._init();
  10364. };
  10365.  
  10366. function ToolbarStyle(xmlFont) {
  10367.     this.isInit = false;
  10368.     
  10369.     this.fontName = null;
  10370.     this.isBold = null;
  10371.     this.isUnderlined = false;
  10372.     this.isItalic = false;
  10373.     this.fontSize = null; //pt
  10374.     this.color = null;
  10375.  
  10376.     var styleString = "";
  10377.     var styleString2 = "";
  10378.  
  10379.     this.getStyleStringWithoutColor = function() {
  10380.         if (!this.isInit) return "";
  10381.  
  10382.         if (!styleString) {
  10383.             if (this.fontName) styleString += "font-family:" + this.fontName + ";";
  10384.             if (this.isBold) styleString += "font-weight:bold;";
  10385.             if (this.isUnderlined) styleString += "text-decoration:underline;";
  10386.             if (this.isItalic) styleString += "font-style:italic;";
  10387.             if (this.fontSize) styleString += "font-size:" + this.fontSize + "pt;";
  10388.         }
  10389.         
  10390.         return styleString;
  10391.     };
  10392.     
  10393.     this.getStyleString = function() {
  10394.         if (!this.isInit) return "";
  10395.  
  10396.         if (!styleString2) {
  10397.             if (this.fontName) styleString2 += "font-family:" + this.fontName + ";";
  10398.             if (this.isBold) styleString2 += "font-weight:bold;";
  10399.             if (this.isUnderlined) styleString2 += "text-decoration:underline;";
  10400.             if (this.isItalic) styleString2 += "font-style:italic;";
  10401.             if (this.fontSize) styleString2 += "font-size:" + this.fontSize + "pt;";
  10402.             if (this.color) styleString2 += "color:" + this.color + ";";
  10403.         }
  10404.         return styleString2;
  10405.     };
  10406.  
  10407.     this._init = function() {
  10408.         this.isInit = true;
  10409.  
  10410.         this.fontName = XML.GetSingleNodeValue(xmlFont, "FONT_NAME", null);
  10411.         this.isBold = XML.GetSingleNodeValueAsBoolean(xmlFont, "BOLD", null);
  10412.         this.isUnderlined = XML.GetSingleNodeValueAsBoolean(xmlFont, "UNDERLINED", null);
  10413.         this.isItalic = XML.GetSingleNodeValueAsBoolean(xmlFont, "ITALIC", null);
  10414.         this.fontSize = XML.GetSingleNodeValue(xmlFont, "SIZE", null);
  10415.         this.color = XML.GetSingleNodeValue(xmlFont, "COLOR", null);
  10416.     };
  10417.  
  10418.     if (xmlFont) this._init();
  10419. };
  10420. function UserComponentsState() {
  10421.     this.weather = new UserComponentState(true, true);
  10422.     this.emailNotifier = new UserComponentState(true, true);
  10423.     this.privacy = new UserComponentState(true, false);
  10424.     this.radio = new UserComponentState(true, true);
  10425.     this.facebook = new UserComponentState(true, true);
  10426. };
  10427. function UserComponentState(available, checked) {
  10428.     this.available = available;
  10429.     this.checked = checked;
  10430. };
  10431. function ToolbarDataManager(toolbarVersion, actingCTID, originalCTID, objToolbarDefaults) {
  10432.     var toolbarData = new ToolbarData();
  10433.     var aSubject = new Object();
  10434.         aSubject.wrappedJSObject = aSubject;
  10435.         aSubject.originalCTID = originalCTID;
  10436.         aSubject.actingCTID = actingCTID;
  10437.  
  10438.     var chromeName = objToolbarDefaults.chromeName;
  10439.  
  10440.     this.notifySettingObservers = function() {
  10441.         notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.settings);
  10442.     };
  10443.  
  10444.     this.updateSettings = function(xmlToolbarSettings, bNotifyObservers, isMC) {
  10445.         //settings is already parsed, and this are not new settings from server
  10446.         if (!xmlToolbarSettings) return;
  10447.  
  10448.         var objMCItem = null;
  10449.         if (isMC) {
  10450.             var objData = new ToolbarItemData(null, ToolbarDataParsingXPCOM.ComponentType.Settings, true, chromeName, originalCTID, actingCTID);
  10451.             objMCItem = new MultiCommunityItem(objData);
  10452.         }
  10453.  
  10454.         var settingsParser = new SettingsParser(xmlToolbarSettings, objMCItem, objToolbarDefaults, originalCTID, actingCTID);
  10455.         toolbarData.publisherItemsHash = settingsParser.getItemsHash();
  10456.  
  10457.         //check if valid, should be at least one publisher component (except the multicommunity component)
  10458.         var invalidCount = (isMC) ? 1 : 0;
  10459.         if (!toolbarData.publisherItemsHash || toolbarData.publisherItemsHash.Count() == invalidCount)
  10460.             return false;
  10461.  
  10462.         toolbarData.generalToolbarInfo = settingsParser.getGeneralToolbarInfo();
  10463.         toolbarData.componentsIds = settingsParser.getComponentsIDs();
  10464.         settingsParser = null;
  10465.  
  10466.         if (bNotifyObservers)
  10467.             this.notifySettingObservers();
  10468.  
  10469.         return true;
  10470.     };
  10471.  
  10472.     this.updateUserAddedComponents = function(xmlUserComponents, bNotifyObservers) {
  10473.         //parse user added by old API components
  10474.         var userComponentsParser = new UserComponentsParser(xmlUserComponents, chromeName, originalCTID, actingCTID, objToolbarDefaults.knownComponents);
  10475.         toolbarData.userItemsHash = userComponentsParser.getItemsHash();
  10476.         userComponentsParser = null;
  10477.  
  10478.         if (bNotifyObservers)
  10479.             notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.userAddComponents);
  10480.     };
  10481.  
  10482.     this.updateThirdPartyComponents = function(xmlThirdPartyComponents, bNotifyObservers) {
  10483.         //parse third party components
  10484.         var thirdPartyComponentsParser = new ThirdPartyComponentsParser(xmlThirdPartyComponents, chromeName, originalCTID, actingCTID, objToolbarDefaults.knownComponents);
  10485.         toolbarData.thirdPartyItemsHash = thirdPartyComponentsParser.getItemsHash();
  10486.         thirdPartyComponentsParser = null;
  10487.  
  10488.         if (bNotifyObservers)
  10489.             notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.thirdParty);
  10490.     };
  10491.  
  10492.     this.updateMyStuffComponents = function(arrXmlMyStuffComponents, bNotifyObservers) {
  10493.         //parse myStuff components
  10494.         var myStuffComponentsParser = new MyStuffParser(arrXmlMyStuffComponents, chromeName, originalCTID, actingCTID, objToolbarDefaults.knownComponents);
  10495.         toolbarData.myStuffItemsHash = myStuffComponentsParser.getItemsHash();
  10496.         toolbarData.myStuffDataHash = myStuffComponentsParser.getDataHash();
  10497.         toolbarData.myStuffUniqueCompIdToCompGuidHash = myStuffComponentsParser.getUniqueCompIdToCompGuidHash();
  10498.         myStuffComponentsParser = null;
  10499.  
  10500.         if (bNotifyObservers)
  10501.             notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.myStuff);
  10502.     };
  10503.  
  10504.     this.updateLanguagePack = function(xmlLanguagePack, bNotifyObservers) {
  10505.         if (!xmlLanguagePack) return;
  10506.  
  10507.         toolbarData.languagePack = new LanguagePackDS(xmlLanguagePack);
  10508.         if (bNotifyObservers)
  10509.             notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.languagePack);
  10510.     };
  10511.  
  10512.     this.getToolbarData = function() {
  10513.         return toolbarData;
  10514.     };
  10515. };
  10516. function BaseParser(knownComponents) {
  10517.     this.isKnownComponent = function(xmlComponent) {
  10518.         //patch for older versions prior to 2.3.0.x
  10519.         if (!knownComponents && xmlComponent.tagName == "TWITTER")
  10520.             return false;
  10521.         
  10522.         return !knownComponents || xmlComponent && knownComponents.isKnownComponent(xmlComponent.tagName);
  10523.     };
  10524. };
  10525. function MyStuffParser(arrXmlMyStuffComponents, chromeName, originalCTID, actingCTID, knownComponents) {
  10526.     BaseParser.call(this, knownComponents);
  10527.     
  10528.     var arrHashMyStuffItems = null;
  10529.     var arrHashMyStuffData = null
  10530.     var arrHashMyStuffUniqueCompIdToCompGuid = null;
  10531.  
  10532.     this.parse = function() {
  10533.         arrHashMyStuffItems = new HashArray();
  10534.         arrHashMyStuffData = new HashArray();
  10535.         arrHashMyStuffUniqueCompIdToCompGuid = new HashArray();
  10536.  
  10537.         var myStuffData = null;
  10538.         var myStuffItem = null;
  10539.         var xmlItem = null;
  10540.         var objToolbarItemData = null
  10541.         var myStuffType = ToolbarDataParsingXPCOM.ComponentType.MyStuff;
  10542.  
  10543.         //add myStuffAdd button item
  10544.         objToolbarItemData = new ToolbarItemData(null, myStuffType, false, chromeName, originalCTID, actingCTID);
  10545.         myStuffItem = (!arrXmlMyStuffComponents || arrXmlMyStuffComponents.length == 0) ?
  10546.             new MyStuffButtonItem(objToolbarItemData) : new MyStuffWithOptionsButtonItem(objToolbarItemData);
  10547.  
  10548.         arrHashMyStuffItems.Add(myStuffItem.UniqueCompID, myStuffItem);
  10549.  
  10550.         if (!arrXmlMyStuffComponents) return;
  10551.  
  10552.         for (var i = 0; i < arrXmlMyStuffComponents.length; i++) {
  10553.             myStuffData = new MyStuffComponentData();
  10554.             xmlItem = myStuffData.initFromXml(arrXmlMyStuffComponents[i]);
  10555.             if (this.isKnownComponent(xmlItem)) {
  10556.                 objToolbarItemData = new ToolbarItemData(xmlItem, myStuffType, false, chromeName, originalCTID, actingCTID);
  10557.  
  10558.                 myStuffItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(objToolbarItemData);
  10559.                 if (myStuffItem && !arrHashMyStuffData.Contains(myStuffData.compGuid) && !arrHashMyStuffItems.Contains(myStuffItem.UniqueCompID)) {
  10560.                     arrHashMyStuffData.Add(myStuffData.compGuid, myStuffData);
  10561.                     arrHashMyStuffItems.Add(myStuffItem.UniqueCompID, myStuffItem);
  10562.                     arrHashMyStuffUniqueCompIdToCompGuid.Add(myStuffItem.UniqueCompID, myStuffData.compGuid);
  10563.                 }
  10564.             }
  10565.         }
  10566.     };
  10567.  
  10568.     this.parse();
  10569.  
  10570.     this.getItemsHash = function() {
  10571.         return arrHashMyStuffItems;
  10572.     };
  10573.  
  10574.     this.getDataHash = function() {
  10575.         return arrHashMyStuffData;
  10576.     };
  10577.  
  10578.     this.getUniqueCompIdToCompGuidHash = function() {
  10579.         return arrHashMyStuffUniqueCompIdToCompGuid;
  10580.     };
  10581. };
  10582.  
  10583. MyStuffParser.prototype = new BaseParser();
  10584. MyStuffParser.constructor = MyStuffParser;
  10585. function SettingsParser(xmlToolbarSettings, objMCItem, objToolbarDefaults, originalCTID, actingCTID) 
  10586. {
  10587.     BaseParser.call(this, objToolbarDefaults.knownComponents);
  10588.     
  10589.     var arrHashToolbarItems = new HashArray();
  10590.     var generalToolbarInfo = null;
  10591.     var strToolbarVersion = objToolbarDefaults.version;
  10592.     var chromeName = objToolbarDefaults.chromeName;
  10593.     var componentsIds = new ComponentsIDs();
  10594.     
  10595.     //if MC item exists, always add it first
  10596.     if (objMCItem)
  10597.         arrHashToolbarItems.Add(objMCItem.UniqueCompID, objMCItem);
  10598.  
  10599.     var isVersionOk = function(xmlComponent) {
  10600.         try {
  10601.             if (!xmlComponent && !xmlComponent.tagName)
  10602.                 return true;
  10603.  
  10604.             var strMaxSupported = null;
  10605.             var strMinSupported = null;
  10606.             var xpathResult = null;
  10607.  
  10608.             xpathResult = xmlComponent.ownerDocument.evaluate("COMPONENT_VERSION_INFO/FF/MAX_VER", xmlComponent, null, 2, null);
  10609.             if (xpathResult) strMaxSupported = xpathResult.stringValue;
  10610.  
  10611.             xpathResult = xmlComponent.ownerDocument.evaluate("COMPONENT_VERSION_INFO/FF/MIN_VER", xmlComponent, null, 2, null);
  10612.             if (xpathResult) strMinSupported = xpathResult.stringValue;
  10613.  
  10614.             if (!strMaxSupported && !strMinSupported)
  10615.                 return true;
  10616.  
  10617.             if (strMaxSupported) {
  10618.                 var iMaxCheck = compareVersions(strToolbarVersion, strMaxSupported)
  10619.                 if (iMaxCheck > 0)
  10620.                     return false;
  10621.             }
  10622.  
  10623.             if (strMinSupported) {
  10624.                 var iMinCheck = compareVersions(strMinSupported, strToolbarVersion)
  10625.                 if (iMinCheck > 0)
  10626.                     return false;
  10627.             }
  10628.  
  10629.             return true;
  10630.  
  10631.         }
  10632.         catch (e) {
  10633.             return true;
  10634.         }
  10635.     };
  10636.  
  10637.     this.setComponentsId = function(oToolbarItem) {
  10638.         var uniqueCompID = oToolbarItem.UniqueCompID;
  10639.  
  10640.         if (oToolbarItem instanceof DynamicMenuItem && oToolbarItem.isMainMenu)
  10641.             componentsIds.MainMenu = uniqueCompID;
  10642.         else if (oToolbarItem instanceof SearchBoxItem)
  10643.             componentsIds.SearchBox = uniqueCompID;
  10644.         else if (oToolbarItem instanceof HighlighterItem)
  10645.             componentsIds.Highlighter = uniqueCompID;
  10646.         else if (oToolbarItem instanceof EMailNotifierItem)
  10647.             componentsIds.EMailNotifier = uniqueCompID;
  10648.         else if (oToolbarItem instanceof PrivacyItem)
  10649.             componentsIds.Privacy = uniqueCompID;
  10650.         else if (oToolbarItem instanceof WeatherItem)
  10651.             componentsIds.Weather = uniqueCompID;
  10652.         else if (oToolbarItem instanceof RadioItem)
  10653.             componentsIds.Radio = uniqueCompID;
  10654.         else if (oToolbarItem instanceof ChatItem)
  10655.             componentsIds.Chat = uniqueCompID;
  10656.         else if (oToolbarItem instanceof FacebookItem)
  10657.             componentsIds.Facebook = uniqueCompID;
  10658.     };
  10659.  
  10660.     this.parseSettings = function() {
  10661.         var mainMenuItem = null;
  10662.         var xmlComponent = null;
  10663.         var oToolbarItem = null;
  10664.         var objData = null;
  10665.         for (var i = 0; i < xmlToolbarSettings.childNodes.length; i++) {
  10666.             xmlComponent = xmlToolbarSettings.childNodes[i];
  10667.             if (isVersionOk(xmlComponent) && this.isKnownComponent(xmlComponent)) {
  10668.                 objData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.Settings, true, chromeName, originalCTID, actingCTID);
  10669.                 oToolbarItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(objData);
  10670.  
  10671.                 if (oToolbarItem) {
  10672.                     //for special components
  10673.                     this.setComponentsId(oToolbarItem);
  10674.                     arrHashToolbarItems.Add(oToolbarItem.UniqueCompID, oToolbarItem);
  10675.                     if (oToolbarItem instanceof DynamicMenuItem && oToolbarItem.isMainMenu)
  10676.                         mainMenuItem = oToolbarItem;
  10677.                 }
  10678.             }
  10679.         }
  10680.  
  10681.         return mainMenuItem;
  10682.     };
  10683.  
  10684.     this.init = function() {
  10685.         var arrXmlFloatMenuItems = new Array();
  10686.         var mainMenuItem = null;
  10687.         var XMLUserSettings = null;
  10688.         var logoIconItem = null;
  10689.  
  10690.         //GENERAL_TOOLBAR_INFO
  10691.         var xmlGeneralToolbarInfo = XML.SelectSingleNode(xmlToolbarSettings, "GENERAL_TOOLBAR_INFO");
  10692.         generalToolbarInfo = new GeneralToolbarInfo(xmlGeneralToolbarInfo, actingCTID, originalCTID, objToolbarDefaults);
  10693.         //TODO: xmlToolbarSettings.removeChild(xmlGeneralToolbarInfo);
  10694.  
  10695.         //USER_SETTINGS
  10696.         var xmlUserSettings = XML.SelectSingleNode(xmlToolbarSettings, "USER_SETTINGS");
  10697.         if (xmlUserSettings) {
  10698.             //TODO: xmlToolbarSettings.removeChild(xmlUserSettings);
  10699.         }
  10700.  
  10701.         //LOGOICON
  10702.         var xmlLogoIcon = XML.SelectSingleNode(xmlToolbarSettings, "LOGOICON");
  10703.         if (xmlLogoIcon) {
  10704.             //TODO: xmlToolbarSettings.removeChild(xmlLogoIcon);
  10705.             logoIconItem = new LogoIconItem(xmlLogoIcon);
  10706.         }
  10707.  
  10708.         //MENUITEM
  10709.         var xmlMenuItem = XML.SelectSingleNode(xmlToolbarSettings, "MENUITEM");
  10710.         if (xmlMenuItem) {
  10711.             //TODO: xmlToolbarSettings.removeChild(xmlMenuItem);
  10712.             arrXmlFloatMenuItems.push(xmlMenuItem);
  10713.         }
  10714.  
  10715.         //parse settings
  10716.         mainMenuItem = this.parseSettings();
  10717.  
  10718.         if (mainMenuItem) {
  10719.             this.updateMainMenu(mainMenuItem, arrXmlFloatMenuItems, logoIconItem);
  10720.         }
  10721.  
  10722.         //add missing personal components from USER_SETTINGS flag
  10723.         this.addMissingUserSettingsComponents(xmlUserSettings);
  10724.  
  10725.         //update personal components with personal components object
  10726.         this.updatePersonalComponents();
  10727.     };
  10728.  
  10729.     this.updateMainMenu = function(mainMenuItem, arrXmlFloatMenuItems, logoIconItem) {
  10730.         mainMenuItem.arrXmlFloatMenuItems = arrXmlFloatMenuItems;
  10731.         if (!logoIconItem || mainMenuItem.IsValidMainMenu) return;
  10732.         
  10733.         if (logoIconItem.tooltip)
  10734.             mainMenuItem.button.tooltip = logoIconItem.tooltip;
  10735.  
  10736.         if (logoIconItem.link)
  10737.             mainMenuItem.link = logoIconItem.link;
  10738.  
  10739.         if (logoIconItem.path)
  10740.             mainMenuItem.button.image = logoIconItem.path;
  10741.     };
  10742.  
  10743.     this.addMissingUserSettingsComponents = function(xmlUserSettings) {
  10744.         var xmlComponent = null;
  10745.         var objItem = null;
  10746.         var objItemData = null;
  10747.  
  10748.         //check to add Email notifier
  10749.         if (!arrHashToolbarItems.Contains(componentsIds.EMailNotifier)) {
  10750.             xmlComponent = XML.SelectSingleNode(xmlUserSettings, "EMAIL_NOTIFIER");
  10751.             if (xmlComponent && isVersionOk(xmlComponent) && this.isKnownComponent(xmlComponent)) {
  10752.                 objItemData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.Settings, false, chromeName, originalCTID, actingCTID);
  10753.                 objItem = new EMailNotifierItem(objItemData);
  10754.                 arrHashToolbarItems.Add(objItem.UniqueCompID, objItem);
  10755.                 componentsIds.EMailNotifier = objItem.UniqueCompID;
  10756.             }
  10757.         }
  10758.  
  10759.         //check to add Privacy
  10760.         if (!arrHashToolbarItems.Contains(componentsIds.Privacy)) {
  10761.             xmlComponent = XML.SelectSingleNode(xmlUserSettings, "PRIVACY_COMPONENT");
  10762.             if (xmlComponent && isVersionOk(xmlComponent) && this.isKnownComponent(xmlComponent)) {
  10763.                 objItemData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.Settings, false, chromeName, originalCTID, actingCTID);
  10764.                 objItem = new PrivacyItem(objItemData);
  10765.                 arrHashToolbarItems.Add(objItem.UniqueCompID, objItem);
  10766.                 componentsIds.Privacy = objItem.UniqueCompID;
  10767.             }
  10768.         }
  10769.  
  10770.         //check to add Radio
  10771.         if (!arrHashToolbarItems.Contains(componentsIds.Radio)) {
  10772.             xmlComponent = XML.SelectSingleNode(xmlUserSettings, "RADIO_PLAYER");
  10773.             if (xmlComponent && isVersionOk(xmlComponent) && this.isKnownComponent(xmlComponent)) {
  10774.                 objItemData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.Settings, false, chromeName, originalCTID, actingCTID);
  10775.                 objItem = new RadioItem(objItemData);
  10776.                 arrHashToolbarItems.Add(objItem.UniqueCompID, objItem);
  10777.                 componentsIds.Radio = objItem.UniqueCompID;
  10778.             }
  10779.         }
  10780.  
  10781.         //check to add Radio
  10782.         if (!arrHashToolbarItems.Contains(componentsIds.Weather)) {
  10783.             xmlComponent = XML.SelectSingleNode(xmlUserSettings, "WEATHER");
  10784.             if (xmlComponent && isVersionOk(xmlComponent) && this.isKnownComponent(xmlComponent)) {
  10785.                 objItemData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.Settings, false, chromeName, originalCTID, actingCTID);
  10786.                 objItem = new WeatherItem(objItemData);
  10787.                 arrHashToolbarItems.Add(objItem.UniqueCompID, objItem);
  10788.                 componentsIds.Weather = objItem.UniqueCompID;
  10789.             }
  10790.         }
  10791.  
  10792.         //check to add Facebook
  10793.         if (!arrHashToolbarItems.Contains(componentsIds.Facebook)) {
  10794.             xmlComponent = XML.SelectSingleNode(xmlUserSettings, "FACEBOOK_COMP");
  10795.             if (xmlComponent && isVersionOk(xmlComponent) && this.isKnownComponent(xmlComponent)) {
  10796.                 objItemData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.Settings, false, chromeName, originalCTID, actingCTID);
  10797.                 objItem = new FacebookItem(objItemData);
  10798.                 arrHashToolbarItems.Add(objItem.UniqueCompID, objItem);
  10799.                 componentsIds.Facebook = objItem.UniqueCompID;
  10800.             }
  10801.         }
  10802.     };
  10803.  
  10804.     this.updatePersonalComponents = function() {
  10805.         var oWeather = arrHashToolbarItems.GetByID(componentsIds.Weather);
  10806.         var oRadio = arrHashToolbarItems.GetByID(componentsIds.Radio);
  10807.         var oEmailNotifier = arrHashToolbarItems.GetByID(componentsIds.EMailNotifier);
  10808.         var oPrivacy = arrHashToolbarItems.GetByID(componentsIds.Privacy);
  10809.         var oFacebook = arrHashToolbarItems.GetByID(componentsIds.Facebook);
  10810.  
  10811.         if (oWeather) oWeather.personalComponentState = generalToolbarInfo.userComponentsState.weather;
  10812.         if (oRadio) oRadio.personalComponentState = generalToolbarInfo.userComponentsState.radio;
  10813.         if (oEmailNotifier) oEmailNotifier.personalComponentState = generalToolbarInfo.userComponentsState.emailNotifier;
  10814.         if (oPrivacy) oPrivacy.personalComponentState = generalToolbarInfo.userComponentsState.privacy;
  10815.         if (oFacebook) oPrivacy.personalComponentState = generalToolbarInfo.userComponentsState.facebook;
  10816.     };
  10817.  
  10818.     this.init();
  10819.  
  10820.     this.getItemsHash = function() {
  10821.         return arrHashToolbarItems;
  10822.     };
  10823.  
  10824.     this.getGeneralToolbarInfo = function() {
  10825.         return generalToolbarInfo;
  10826.     };
  10827.  
  10828.     this.getComponentsIDs = function() {
  10829.         return componentsIds;
  10830.     };
  10831. };
  10832.  
  10833. SettingsParser.prototype = new BaseParser();
  10834. SettingsParser.constructor = SettingsParser;
  10835. function ThirdPartyComponentsParser(xmlThirdPartyComponents, chromeName, originalCTID, actingCTID, knownComponents) {
  10836.     BaseParser.call(this, knownComponents);
  10837.     var arrHashToolbarItems = null;
  10838.  
  10839.     this.parse = function() {
  10840.         arrHashToolbarItems = new HashArray();
  10841.         var xmlComponent = null;
  10842.         var oToolbarItem = null;
  10843.         var objData = null;
  10844.  
  10845.         for (var i = 0; i < xmlThirdPartyComponents.childNodes.length; i++) {
  10846.             xmlComponent = xmlThirdPartyComponents.childNodes[i];
  10847.             if (this.isKnownComponent(xmlComponent)) {
  10848.                 objData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.ThirdParty, false, chromeName, originalCTID, actingCTID);
  10849.                 oToolbarItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(objData);
  10850.  
  10851.                 if (oToolbarItem)
  10852.                     arrHashToolbarItems.Add(oToolbarItem.UniqueCompID, oToolbarItem);
  10853.             }
  10854.         }
  10855.     };
  10856.  
  10857.     this.getItemsHash = function() {
  10858.         return arrHashToolbarItems;
  10859.     };
  10860.  
  10861.     if (xmlThirdPartyComponents) this.parse();
  10862. };
  10863.  
  10864. ThirdPartyComponentsParser.prototype = new BaseParser();
  10865. ThirdPartyComponentsParser.constructor = ThirdPartyComponentsParser;
  10866. function UserComponentsParser(xmlUserComponents, chromeName, originalCTID, actingCTID, knownComponents) {
  10867.     BaseParser.call(this, knownComponents);
  10868.     var arrHashToolbarItems = null;
  10869.  
  10870.     this.parse = function() {
  10871.         arrHashToolbarItems = new HashArray();
  10872.         var xmlComponent = null;
  10873.         var oToolbarItem = null;
  10874.         var objData = null;
  10875.         for (var i = 0; i < xmlUserComponents.childNodes.length; i++) {
  10876.             xmlComponent = xmlUserComponents.childNodes[i];
  10877.             if (this.isKnownComponent(xmlComponent)) {
  10878.                 objData = new ToolbarItemData(xmlComponent, ToolbarDataParsingXPCOM.ComponentType.UserAdded, false, chromeName, originalCTID, actingCTID);
  10879.                 oToolbarItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(objData);
  10880.  
  10881.                 if (oToolbarItem)
  10882.                     arrHashToolbarItems.Add(oToolbarItem.UniqueCompID, oToolbarItem);
  10883.             }
  10884.         }
  10885.     };
  10886.  
  10887.     this.getItemsHash = function() {
  10888.         return arrHashToolbarItems;
  10889.     };
  10890.  
  10891.     if (xmlUserComponents) this.parse();
  10892. };
  10893.  
  10894. UserComponentsParser.prototype = new BaseParser();
  10895. UserComponentsParser.constructor = UserComponentsParser;
  10896. function DataNodeFactory() {
  10897.     this.getDataObject = function(xmlData) {
  10898.         var type = XML.GetSingleNodeValue(xmlData, "TYPE");
  10899.         var data = null;
  10900.         var strNode = "";
  10901.         switch (type) {
  10902.             case ToolbarDataParsingXPCOM.dataNodeTypes.COMMAND:
  10903.                 var xpathResult = xmlData.ownerDocument.evaluate("COMMAND/TYPE", xmlData, null, 2, null);
  10904.                 if (xpathResult && xpathResult.stringValue == ToolbarDataParsingXPCOM.dataNodeTypes.TOGGLE_COMMAND) {
  10905.                     data = new DataNodeToggleCommand();
  10906.                     strNode = ToolbarDataParsingXPCOM.dataNodeTypes.TOGGLE_COMMAND;
  10907.                 }
  10908.                 else {
  10909.                     data = new DataNodeCommand();
  10910.                     strNode = ToolbarDataParsingXPCOM.dataNodeTypes.COMMAND;
  10911.                 }
  10912.                 break;
  10913.             case ToolbarDataParsingXPCOM.dataNodeTypes.LINK:
  10914.                 data = new DataNodeLink();
  10915.                 strNode = ToolbarDataParsingXPCOM.dataNodeTypes.LINK;
  10916.                 break;
  10917.             case ToolbarDataParsingXPCOM.dataNodeTypes.POP_HTML:
  10918.                 data = new DataNodePopHtml();
  10919.                 strNode = ToolbarDataParsingXPCOM.dataNodeTypes.POP_HTML;
  10920.                 break;
  10921.             case ToolbarDataParsingXPCOM.dataNodeTypes.APPLICATION:
  10922.                 data = new DataNodeApplication();
  10923.                 strNode = ToolbarDataParsingXPCOM.dataNodeTypes.APPLICATION;
  10924.                 break;
  10925.             case ToolbarDataParsingXPCOM.dataNodeTypes.RSS:
  10926.                 data = new DataNodeRss();
  10927.                 strNode = ToolbarDataParsingXPCOM.dataNodeTypes.RSS;
  10928.                 break;
  10929.             default: break;
  10930.         }
  10931.  
  10932.         if (data)
  10933.             data.init(XML.SelectSingleNode(xmlData, strNode));
  10934.  
  10935.         return data;
  10936.     };
  10937. };
  10938. function DataNodeTypes() {
  10939.     this.COMMAND = "COMMAND";
  10940.     this.TOGGLE_COMMAND = "TOGGLE_COMMAND";
  10941.     this.LINK = "LINK";
  10942.     this.POP_HTML = "POP_HTML";
  10943.     this.APPLICATION = "APPLICATION";
  10944.     this.RSS = "RSS";
  10945. };
  10946. function DataNodeApplication() {
  10947.     this.exeAlias = "";
  10948.     this.params = "";
  10949.     this.link = "";
  10950.     this.type = ToolbarDataParsingXPCOM.dataNodeTypes.APPLICATION;
  10951.  
  10952.     this.init = function(xmlApplication) {
  10953.         if (!xmlApplication) return;
  10954.         
  10955.         this.exeAlias = XML.GetSingleNodeValue(xmlApplication, "EXE_ALIAS");
  10956.         this.params = XML.GetSingleNodeValue(xmlApplication, "PARAMS");
  10957.         this.link = XML.GetSingleNodeValue(xmlApplication, "APP_NOT_FOUND_URL");
  10958.     };
  10959.  
  10960.     this.isValid = function() {
  10961.         if (!this.exeAlias) return false;
  10962.  
  10963.         return true;
  10964.     };
  10965. };
  10966.  
  10967. DataNodeApplication.prototype = new DataNodeBase();
  10968. function DataNodeBase() {
  10969.     this.type = "";
  10970.     this.init = function() { };
  10971.     this.isValid = function() { };
  10972. }
  10973. function DataNodeCommand() {
  10974.     this.command = "";
  10975.     this.type = ToolbarDataParsingXPCOM.dataNodeTypes.COMMAND;
  10976.  
  10977.     this.init = function(xmlCommand) {
  10978.         if (!xmlCommand) return;
  10979.         
  10980.         this.command = XML.GetSingleNodeValue(xmlCommand, "TYPE");
  10981.     };
  10982.  
  10983.     this.isValid = function() {
  10984.         if (!this.command) return false;
  10985.  
  10986.         return true;
  10987.     };
  10988. };
  10989.  
  10990. DataNodeCommand.prototype = new DataNodeBase();
  10991. function DataNodeLink() {
  10992.     this.link = "";
  10993.     this.target = "";
  10994.     this.type = ToolbarDataParsingXPCOM.dataNodeTypes.LINK;
  10995.  
  10996.     this.init = function(xmlLink) {
  10997.         if (!xmlLink) return;
  10998.  
  10999.         this.link = XML.GetSingleNodeValue(xmlLink, "URL");
  11000.         this.target = XML.GetSingleNodeValue(xmlLink, "TARGET");
  11001.     };
  11002.     
  11003.     this.isValid = function() {
  11004.         if (!this.link) return false;
  11005.  
  11006.         return true;
  11007.     };
  11008. };
  11009.  
  11010. DataNodeLink.prototype = new DataNodeBase();
  11011. function DataNodePopHtml() {
  11012.     //open position types
  11013.     this.openPositionTypes = new Object();
  11014.     this.openPositionTypes.click = "CLICK";
  11015.     this.openPositionTypes.center = "CENTER";
  11016.     this.openPositionTypes.alignment = "ALIGNMENT";
  11017.     this.openPositionTypes.offset = "OFFSET";
  11018.  
  11019.     this.openPositionTypes.verticalAlignmentTop = "T";
  11020.     this.openPositionTypes.verticalAlignmentBottom = "B";
  11021.     this.openPositionTypes.horizontalAlignmentLeft = "L";
  11022.     this.openPositionTypes.horizontalAlignmentRight = "R";
  11023.     
  11024.     
  11025.     this.popHtmlUrl = "";
  11026.     this.defaultTarget = "";
  11027.     this.width = "";
  11028.     this.height = "";
  11029.     this.offsetX = "";
  11030.     this.offsetY = "";
  11031.     this.scrollV = false;
  11032.     this.scrollH = false;
  11033.     this.resizable = true;
  11034.     this.titlebar = true;
  11035.     this.closeOnExternalClick = false;
  11036.     this.closeButton = true;
  11037.     this.saveLocation = true;
  11038.     this.saveSize = true;
  11039.     this.openPositionType = "";
  11040.     this.openPositionData = new Object();
  11041.  
  11042.     this.parentElement = null;
  11043.     this.title = "";
  11044.     this.isUser = false;
  11045.     this.componentId = "";
  11046.     this.elementId = "";
  11047.     this.compType = "";
  11048.     this.source = "";
  11049.     this.gadgetType = "";
  11050.     this.facebookGagetType = "";
  11051.     this.titleIconUrl = "";
  11052.     this.chatRoomId = "";
  11053.     
  11054.     this.type = ToolbarDataParsingXPCOM.dataNodeTypes.POP_HTML;
  11055.  
  11056.     this.init = function(xmlPopHtml) {
  11057.         if (!xmlPopHtml) return;
  11058.  
  11059.         this.popHtmlUrl = XML.GetSingleNodeValue(xmlPopHtml, "URL");
  11060.         this.defaultTarget = XML.GetSingleNodeValue(xmlPopHtml, "DEFAULT_TARGET");
  11061.         this.width = XML.GetSingleNodeValueAsInteger(xmlPopHtml, "WIDTH");
  11062.         this.height = XML.GetSingleNodeValueAsInteger(xmlPopHtml, "HEIGHT");
  11063.         this.offsetX = XML.GetSingleNodeValueAsInteger(xmlPopHtml, "OFFSET_X");
  11064.         this.offsetY = XML.GetSingleNodeValueAsInteger(xmlPopHtml, "OFFSET_Y");
  11065.  
  11066.         this.scrollV = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "V_SCROLL", false);
  11067.         this.scrollH = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "H_SCROLL", false);
  11068.         this.resizable = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "RESIZABLE", true);
  11069.         this.titlebar = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "TITLEBAR", true);
  11070.         this.closeOnExternalClick = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "CLOSE_ON_EXTERNAL_CLICK", false);
  11071.         this.closeButton = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "CLOSE_BUTTON", true);
  11072.         this.saveLocation = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "SAVE_LOCATION", true);
  11073.         this.saveSize = XML.GetSingleNodeValueAsBoolean(xmlPopHtml, "SAVE_RESIZED_SIZE", true);
  11074.         var openPosition = XML.SelectSingleNode(xmlPopHtml, "OPEN_POSITION");
  11075.         if (openPosition) {
  11076.             this.openPositionType = XML.GetSingleNodeValue(openPosition, "TYPE");
  11077.             switch (this.openPositionType) {
  11078.                 case this.openPositionTypes.alignment:
  11079.                     var vAlign = XML.GetSingleNodeValue(openPosition, "VERTICAL");
  11080.                     var hAlign = XML.GetSingleNodeValue(openPosition, "HORIZONTAL");
  11081.                     
  11082.                     if (vAlign && vAlign.toLowerCase() == "t")
  11083.                         this.openPositionData.vertical = this.openPositionTypes.verticalAlignmentTop;
  11084.                     else if (vAlign && vAlign.toLowerCase() == "b")
  11085.                         this.openPositionData.vertical = this.openPositionTypes.verticalAlignmentBottom;
  11086.  
  11087.                     if (hAlign && hAlign.toLowerCase() == "l")
  11088.                         this.openPositionData.horizontal = this.openPositionTypes.horizontalAlignmentLeft;
  11089.                     else if (hAlign && hAlign.toLowerCase() == "r")
  11090.                         this.openPositionData.horizontal = this.openPositionTypes.horizontalAlignmentRight;
  11091.  
  11092.                     break;
  11093.                 case this.openPositionTypes.offset:
  11094.                     this.openPositionData.offsetX = XML.GetSingleNodeValueAsInteger(openPosition, "X", 0);
  11095.                     this.openPositionData.offsetY = XML.GetSingleNodeValueAsInteger(openPosition, "Y", 0);
  11096.             }
  11097.         }
  11098.  
  11099.         if (!this.openPositionType) {
  11100.             this.openPositionType = this.openPositionTypes.alignment;
  11101.             this.openPositionData.vertical = this.openPositionTypes.verticalAlignmentBottom;
  11102.         }
  11103.     };
  11104.  
  11105.     this.fillPositionFlags = function(openPosition) {
  11106.         if (openPosition.indexOf("click") != -1) {
  11107.             this.openPositionType = this.openPositionTypes.click;
  11108.         }
  11109.         else if (openPosition.indexOf("center") != -1) {
  11110.             this.openPositionType = this.openPositionTypes.center;
  11111.         }
  11112.         else if (openPosition.indexOf("alignment") != -1) {
  11113.             this.openPositionType = this.openPositionTypes.alignment;
  11114.             var arrTemp = openPosition.split(":");
  11115.             if (arrTemp.length == 2) {
  11116.                 var params = arrTemp[1];
  11117.  
  11118.                 if (params.indexOf("t") != -1) this.openPositionData.vertical = this.openPositionTypes.verticalAlignmentTop;
  11119.                 if (params.indexOf("b") != -1) this.openPositionData.vertical = this.openPositionTypes.verticalAlignmentBottom;
  11120.                 if (params.indexOf("l") != -1) this.openPositionData.horizontal = this.openPositionTypes.horizontalAlignmentLeft;
  11121.                 if (params.indexOf("r") != -1) this.openPositionData.horizontal = this.openPositionTypes.horizontalAlignmentRight;
  11122.             }
  11123.         }
  11124.         else if (openPosition.indexOf("offset") != -1) {
  11125.             this.openPositionType = this.openPositionTypes.offset;
  11126.             var arrTemp = openPosition.split(":");
  11127.             if (arrTemp.length == 2) {
  11128.                 var params = arrTemp[1];
  11129.                 params = params.replace(/\(/, "").replace(/\)/, "");
  11130.                 var arrXY = params.split(";");
  11131.                 if (arrXY.length == 2) {
  11132.                     this.openPositionData.offsetX = parseInt(arrXY[0]);
  11133.                     this.openPositionData.offsetY = parseInt(arrXY[1]);
  11134.                 }
  11135.             }
  11136.         }
  11137.     };
  11138.  
  11139.     this.initFeatures = function(strFeatures) {
  11140.         //default click
  11141.         this.openPositionType = this.openPositionTypes.click;
  11142.         if (!strFeatures) return;
  11143.  
  11144.         var arrFeatures = strFeatures.split(",");
  11145.         var keyValue = "";
  11146.         for (var i = 0; i < arrFeatures.length; i++) {
  11147.             keyValue = arrFeatures[i].toLowerCase().split("=");
  11148.             switch (keyValue[0]) {
  11149.                 case "resizable": this.resizable = parseFeaturedBool(keyValue[1], true); break;
  11150.                 case "vscroll": this.scrollV = parseFeaturedBool(keyValue[1], true); break;
  11151.                 case "hscroll": this.scrollH = parseFeaturedBool(keyValue[1], true); break;
  11152.                 case "titlebar": this.titlebar = parseFeaturedBool(keyValue[1], true); break;
  11153.                 case "closeonexternalclick": this.closeOnExternalClick = parseFeaturedBool(keyValue[1], false); break;
  11154.                 case "closebutton": this.closeButton = parseFeaturedBool(keyValue[1], true); break;
  11155.                 case "savelocation": this.saveLocation = parseFeaturedBool(keyValue[1], true); break;
  11156.                 case "saveresizedsize": this.saveSize = parseFeaturedBool(keyValue[1], true); break;
  11157.                 case "openposition": this.fillPositionFlags(keyValue[1]); break;
  11158.             }
  11159.         }
  11160.     };
  11161.  
  11162.     this.isValid = function() {
  11163.         if (!this.popHtmlUrl) return false;
  11164.  
  11165.         return true;
  11166.     };
  11167. };
  11168.  
  11169. DataNodePopHtml.prototype = new DataNodeBase();
  11170. function DataNodeRss() {
  11171.     this.link = "";
  11172.     this.interval = "";
  11173.     this.type = ToolbarDataParsingXPCOM.dataNodeTypes.RSS;
  11174.  
  11175.     this.init = function(xmlRss) {
  11176.         if (!xmlRss) return;
  11177.  
  11178.         this.link = XML.GetSingleNodeValue(xmlRss, "URL");
  11179.         this.interval = XML.GetSingleNodeValue(xmlRss, "INTERVAL");
  11180.     };
  11181.  
  11182.     this.isValid = function() {
  11183.         if (!this.link || !this.interval) return false;
  11184.  
  11185.         return true;
  11186.     };
  11187. };
  11188.  
  11189. DataNodeRss.prototype = new DataNodeBase();
  11190. function DataNodeToggleCommand() {
  11191.     this.state0 = new DataNodeToggleCommandState();
  11192.     this.state1 = new DataNodeToggleCommandState();
  11193.     this.type = ToolbarDataParsingXPCOM.dataNodeTypes.TOGGLE_COMMAND;
  11194.     
  11195.     this.init = function(xmlToggleCommand) {
  11196.         if (!xmlToggleCommand) return;
  11197.         
  11198.         this.state0.init(XML.SelectSingleNode(xmlToggleCommand, "STATE_0"));
  11199.         this.state1.init(XML.SelectSingleNode(xmlToggleCommand, "STATE_1"));
  11200.     };
  11201.  
  11202.     this.isValid = function() {
  11203.         if (!this.state0.command || !this.state1.command) return false;
  11204.  
  11205.         return true;
  11206.     };
  11207. };
  11208.  
  11209. function DataNodeToggleCommandState() {
  11210.     this.command = "";
  11211.     this.caption = "";
  11212.     this.iconUrl = "";
  11213.     this.tooltip = "";
  11214.  
  11215.     this.init = function(xmlState) {
  11216.         if (!xmlState) return;
  11217.  
  11218.         this.command = XML.GetSingleNodeValue(xmlState, "COMMAND");
  11219.         this.caption = XML.GetSingleNodeValue(xmlState, "CAPTION");
  11220.         this.iconUrl = XML.GetSingleNodeValue(xmlState, "ICON_URL");
  11221.         this.tooltip = XML.GetSingleNodeValue(xmlState, "HINT");
  11222.     };
  11223. };
  11224.  
  11225. DataNodeCommand.prototype = new DataNodeBase();
  11226. function ToolbarItemsFactory()
  11227. {
  11228.     this.GetInstance = function(objToolbarItemData) {
  11229.         switch (objToolbarItemData.xmlNode.tagName) {
  11230.             case "DYNAMIC_MENU":
  11231.                 return new DynamicMenuItem(objToolbarItemData);
  11232.             case "LINK_BUTTONITEM":
  11233.             case "SPECIAL_COMMAND_ITEM":
  11234.             case "BUTTON":
  11235.                 return new ButtonItem(objToolbarItemData);
  11236.             case "BROWSER_COMPONENT":
  11237.                 return new BrowserItem(objToolbarItemData);
  11238.             case "SEARCH":
  11239.                 return new SearchBoxItem(objToolbarItemData);
  11240.             case "HIGHLIGHTER":
  11241.                 return new HighlighterItem(objToolbarItemData);
  11242.             case "RSS_FEED_ITEM":
  11243.                 return new FeedItem(objToolbarItemData);
  11244.             case "SEPERATORITEM":
  11245.                 return new SeparatorItem(objToolbarItemData);
  11246.             case "PRIVACY_COMPONENT":
  11247.                 return new PrivacyItem(objToolbarItemData);
  11248.             case "EXTERNAL_COMPONENT":
  11249.                 return new ExternalComponentItem(objToolbarItemData);
  11250.             case "EMAIL_NOTIFIER":
  11251.                 return new EMailNotifierItem(objToolbarItemData);
  11252.             case "MULTI_RSS":
  11253.                 return new MultiFeedItem(objToolbarItemData);
  11254.             case "WEATHER":
  11255.                 return new WeatherItem(objToolbarItemData);
  11256.             case "LABEL":
  11257.                 return new LabelItem(objToolbarItemData);
  11258.             case "RADIO_PLAYER":
  11259.                 return new RadioItem(objToolbarItemData);
  11260.             case "MULTI_COMMUNITY":
  11261.                 return new MultiCommunityItem(objToolbarItemData);
  11262.             case "EMAIL_NOTIFIER_NEW":
  11263.                 return new EmailNotifierNewItem(objToolbarItemData);
  11264.             case "TOGGLE_COMPONENT":
  11265.                 return new ToggleItem(objToolbarItemData);
  11266.             case "CHAT":
  11267.                 return new ChatItem(objToolbarItemData);
  11268.             case "TWITTER":
  11269.                 return new TwitterItem(objToolbarItemData);
  11270.             case "FACEBOOK_COMP":
  11271.                 return new FacebookItem(objToolbarItemData);
  11272.             default:
  11273.                 return null;
  11274.         }
  11275.     };
  11276. };
  11277. var ToolbarManagerConst =
  11278. {
  11279.     settingsFilename: "LocalSettings.txt",
  11280.     languagePackFilename: "LanguagePack.xml",
  11281.     thirdPartyFilename: "ThirdPartyComponents.xml",
  11282.     userComponentsFilename: "UserAdditionalComponents.xml",
  11283.     languagePackFilename: "LanguagePack.xml",
  11284.     myStuffFolder: "MyStuffComponents"
  11285. };
  11286. var ToolbarManagerPrefsConsts =
  11287. {
  11288.     FixPageNotFoundErrorsIsEnabled: "FixPageNotFoundErrors",
  11289.     MyStuffEnabled: "MyStuffEnabled"
  11290. };
  11291. function ToolbarDefaultsDS() {
  11292.     this.settingsUrl = "";
  11293.     this.loginUrl = "";
  11294.     this.thirdPartyUrl = "";
  11295.     this.languagePackUrl = "";
  11296.     this.webServerUrl = "";
  11297.     this.myStuffUrl = "";
  11298.     this.myStuffSearchUrl = "";
  11299.     this.myStuffEnabled = true;
  11300.     this.isMC = false;
  11301.     this.isGrouping = false;
  11302.     this.version = "";
  11303.     this.chromeName = "";
  11304.     this.fix404Enabled = false;
  11305.     this.fix404Checked = false;
  11306.     this.sendValidationData = false;
  11307.     this.alertSource = "";
  11308.     this.knownComponents = null;
  11309.     this.searchInNewTab = false;
  11310. };
  11311. var MyStuffFunctions =
  11312. {
  11313.     DEFAULT_PUBLISHER_MIN_WIDTH: 400,
  11314.  
  11315.     setComponentShown: function(myStuffDataHash, myStuffItemsHash, compGuid) {
  11316.         //show it if hidden by user, for user to see that it's added
  11317.         var myStuffData = myStuffDataHash.GetByID(compGuid);
  11318.         var oItem = myStuffItemsHash.GetByID(myStuffData.uniqueCompId);
  11319.         if (oItem && !oItem.isShow())
  11320.             oItem.setShowState(true);
  11321.     },
  11322.  
  11323.     getMyStuffComponentFilename: function(compGuid) {
  11324.         return ToolbarManagerConst.myStuffFolder + Dir.sep + compGuid + ".xml";
  11325.     },
  11326.  
  11327.     getMyStuffListFilename: function() {
  11328.         return ToolbarManagerConst.myStuffFolder + Dir.sep + "list.json";
  11329.     },
  11330.  
  11331.     isSupportedComponent: function(xmlMyStuffComponent, knownComponents) {
  11332.         //test component
  11333.         try {
  11334.             var xmlComponent = XML.SelectSingleNode(xmlMyStuffComponent, "COMPONENT_XML");
  11335.             //patch for twitter
  11336.             if (!knownComponents && xmlComponent.firstChild.tagName == "TWITTER")
  11337.                 return false;
  11338.                 
  11339.             if (knownComponents && !knownComponents.isKnownComponent(xmlComponent.firstChild.tagName))
  11340.                 return false;
  11341.  
  11342.             var itemData = new ToolbarItemData(xmlComponent.firstChild, ToolbarDataParsingXPCOM.ComponentType.MyStuff, false, "", "CT", "CT");
  11343.             var oItem = ToolbarDataParsingXPCOM.toolbarItemsFactory.GetInstance(itemData);
  11344.             return oItem != null;
  11345.         }
  11346.         catch (ex) {
  11347.             Logging.LogToConsole(ex);
  11348.             return true;
  11349.         }
  11350.     },
  11351.  
  11352.     loadMyStuffComponents: function(oIO) {
  11353.         var arrList = this.readListFileToArray(oIO);
  11354.         if (!arrList || arrList.length == 0) return null;
  11355.  
  11356.         var compGuid = "";
  11357.         var strFilename = "";
  11358.         var strMyStuffComponent = "";
  11359.         var xmlMyStuffComponent = null;
  11360.         var arrXmlComponents = new Array();
  11361.  
  11362.         for (var i = 0; i < arrList.length; i++) {
  11363.             compGuid = arrList[i];
  11364.             strFilename = this.getMyStuffComponentFilename(compGuid);
  11365.             strMyStuffComponent = oIO.readToolbarFile(strFilename, false);
  11366.             if (strMyStuffComponent) {
  11367.                 xmlMyStuffComponent = XML.GetXmlDocument(strMyStuffComponent);
  11368.                 if (xmlMyStuffComponent) {
  11369.                     xmlMyStuffComponent = xmlMyStuffComponent.documentElement;
  11370.                     arrXmlComponents.push(xmlMyStuffComponent);
  11371.                 }
  11372.             }
  11373.         }
  11374.  
  11375.         return arrXmlComponents;
  11376.     },
  11377.  
  11378.     readListFileToArray: function(oIO) {
  11379.         var strListFilename = this.getMyStuffListFilename();
  11380.         var strListJson = oIO.readToolbarFile(strListFilename, false);
  11381.  
  11382.         if (!strListJson) return null;
  11383.         var arrList = null;
  11384.         try {
  11385.             arrList = JSON.parse(strListJson);
  11386.         }
  11387.         catch (ex) {
  11388.             Logging.LogToConsole(ex);
  11389.         }
  11390.  
  11391.         return arrList;
  11392.     },
  11393.  
  11394.     writeListFileFromArray: function(arrList, oIO) {
  11395.         var strJson = (!arrList || arrList.length == 0) ? "" : "[\"" + arrList.join("\",\"") + "\"]";
  11396.         oIO.writeToolbarFile(strJson, this.getMyStuffListFilename());
  11397.     },
  11398.  
  11399.     deleteMyStuffComponent: function(compGuid, oIO) {
  11400.         //delete component file
  11401.         var strFilename = this.getMyStuffComponentFilename(compGuid);
  11402.         oIO.deleteFile(strFilename);
  11403.  
  11404.         //update components list
  11405.         var arrList = this.readListFileToArray(oIO);
  11406.         if (!arrList || arrList.length == 0) return;
  11407.  
  11408.         for (var i = 0; i < arrList.length; i++) {
  11409.             if (arrList[i] == compGuid) {
  11410.                 arrList.splice(i, 1);
  11411.                 this.writeListFileFromArray(arrList, oIO);
  11412.                 break;
  11413.             }
  11414.         }
  11415.     },
  11416.  
  11417.     updateMyStuffComponents: function(positionsHash, myStuffDataHash, myStuffItemsHash, myStuffUniqueCompIdToCompGuidHash, oIO) {
  11418.         var oData = null;
  11419.         var compFilename = "";
  11420.         for (var i = 0; i < myStuffDataHash.Count(); i++) {
  11421.             oData = myStuffDataHash.GetByIndex(i);
  11422.             if (!positionsHash.Contains(oData.uniqueCompId)) {
  11423.                 compFilename = this.getMyStuffComponentFilename(oData.compGuid);
  11424.                 //set component visible before delete
  11425.                 this.setComponentShown(myStuffDataHash, myStuffItemsHash, oData.compGuid);
  11426.                 oIO.deleteFile(compFilename);
  11427.             }
  11428.         }
  11429.  
  11430.         //create list of compGuid from list of UniqueCompId
  11431.         var arrList = new Array();
  11432.         var compGuid = "";
  11433.         for (var i = 0; i < positionsHash.Count(); i++) {
  11434.             compGuid = myStuffUniqueCompIdToCompGuidHash.GetByID(positionsHash.GetByIndex(i));
  11435.             arrList.push(compGuid);
  11436.         }
  11437.  
  11438.         this.writeListFileFromArray(arrList, oIO);
  11439.     },
  11440.  
  11441.     onMyStuffResponse: function(myStuffRS, compGuid, myStuffDataHash, oIO, isFromApi, knownComponents) {
  11442.         if (!isFromApi && myStuffRS.flags == ToolbarDataParsingXPCOM.myStuff.responseFlags.DELETED) {
  11443.             this.deleteMyStuffComponent(compGuid, oIO);
  11444.             return;
  11445.         }
  11446.  
  11447.         if (myStuffRS.flags != ToolbarDataParsingXPCOM.myStuff.responseFlags.MODIFIED && isFromApi) return;
  11448.  
  11449.         var myStuffData = (myStuffDataHash) ? myStuffDataHash.GetByID(compGuid) : null;
  11450.         var isNew = false;
  11451.         //new component
  11452.         if (!myStuffData) {
  11453.             myStuffData = new MyStuffComponentData();
  11454.             myStuffData.compGuid = compGuid;
  11455.             isNew = true;
  11456.         }
  11457.  
  11458.         var xmlComponent = myStuffData.updateFromResponse(myStuffRS);
  11459.         var xmlMyStuffComponent = myStuffData.toXml(xmlComponent);
  11460.  
  11461.         if (!this.isSupportedComponent(xmlMyStuffComponent, knownComponents)) {
  11462.             myStuffRS.flags = ToolbarDataParsingXPCOM.myStuff.responseFlags.UNSUPPORTED;
  11463.             return;
  11464.         }
  11465.  
  11466.         var strFileName = MyStuffFunctions.getMyStuffComponentFilename(compGuid);
  11467.         oIO.writeToolbarFile(XML.GetStringXml(xmlMyStuffComponent), strFileName, false);
  11468.  
  11469.         if (isNew) {
  11470.             var arrList = this.readListFileToArray(oIO);
  11471.             if (!arrList) {
  11472.                 arrList = new Array();
  11473.                 arrList.push(compGuid);
  11474.             }
  11475.             else
  11476.                 arrList.splice(0, 0, compGuid);
  11477.  
  11478.             this.writeListFileFromArray(arrList, oIO);
  11479.         }
  11480.     },
  11481.  
  11482.     addMyStuffComponent: function(compGuid, compInstanceGuid, myStuffDataHash, myStuffItemsHash, myStuffManager, oIO, responseCallback) {
  11483.         //exists
  11484.         if (myStuffDataHash && myStuffDataHash.Contains(compGuid)) {
  11485.             this.setComponentShown(myStuffDataHash, myStuffItemsHash, compGuid);
  11486.             //reposition
  11487.             var arrList = this.readListFileToArray(oIO);
  11488.             var i = 0;
  11489.             for (; i < arrList.length; i++)
  11490.                 if (arrList[i] == compGuid) break;
  11491.  
  11492.             arrList.splice(i, 1);
  11493.             arrList.splice(0, 0, compGuid);
  11494.             this.writeListFileFromArray(arrList, oIO);
  11495.  
  11496.             return true;
  11497.         }
  11498.         //not exists, get from server
  11499.         else {
  11500.             var objMyStuffData = new MyStuffComponentData();
  11501.             objMyStuffData.compGuid = compGuid;
  11502.             objMyStuffData.compInstanceGuid = compInstanceGuid;
  11503.             var arrMyStuff = new Array();
  11504.             arrMyStuff.push(objMyStuffData);
  11505.             myStuffManager.request(arrMyStuff, responseCallback, true);
  11506.             return false;
  11507.         }
  11508.     },
  11509.  
  11510.     isSuccessFlags: function(flags) {
  11511.         return (flags == ToolbarDataParsingXPCOM.myStuff.responseFlags.NOT_MODIFIED ||
  11512.                     flags == ToolbarDataParsingXPCOM.myStuff.responseFlags.MODIFIED);
  11513.     },
  11514.  
  11515.     notifyUIEvent: function(flags, isSuccess, originalCTID) {
  11516.         var win = getWindow();
  11517.         var thatToolbarManager = win["EBToolbarManager_" + originalCTID];
  11518.         if(thatToolbarManager && thatToolbarManager.myStuffManager && thatToolbarManager.myStuffManager.onApiAddStuffResponse)
  11519.             thatToolbarManager.myStuffManager.onApiAddStuffResponse(flags, isSuccess);
  11520.     }
  11521. };
  11522. function ToolbarManager(originalCTID, actingCTID, objOnReadyCallback) {
  11523.     var isInit = false;
  11524.     this.originalCTID = originalCTID;
  11525.     this.actingCTID = actingCTID;
  11526.     this.toolbarDefaults = null;
  11527.     this.notifyReadyOnceFunction = (typeof objOnReadyCallback != "undefined") ? objOnReadyCallback : null;
  11528.     this.refCount = 0;
  11529.     
  11530.     var oPrefs = new PrefManager(this.originalCTID, this.actingCTID);
  11531.     var oIO = new IO(this.originalCTID, this.actingCTID);
  11532.  
  11533.     var toolbarDataManager = null;
  11534.     
  11535.     //services manager
  11536.     var settingsManager = null;
  11537.     var loginManager = null;
  11538.     var thirdPartyManager = null;
  11539.     var languagePackManager = null;
  11540.     var myStuffManager = null;
  11541.  
  11542.     this._initManagers = function() {
  11543.         settingsManager = new SettingsManager(this.toolbarDefaults.settingsUrl, this.toolbarDefaults.version, this.originalCTID, this.actingCTID, oPrefs, this.onSettingsModified, this);
  11544.         loginManager = new LoginManager(this.toolbarDefaults.loginUrl, originalCTID, actingCTID, oPrefs, this.toolbarDefaults, this._refreshToolbarAfterFirstLogin, this);
  11545.         thirdPartyManager = new ThirdPartyManager(this.toolbarDefaults.thirdPartyUrl, originalCTID, actingCTID, oPrefs, this.onThirdPartyModified, this);
  11546.         languagePackManager = new LanguagePackManager(this.toolbarDefaults.languagePackUrl, originalCTID, actingCTID, this.toolbarDefaults.version, oPrefs, this.onLanguagePackChange, this);
  11547.         myStuffManager = new MyStuffServiceManager(this.toolbarDefaults.myStuffUrl, oPrefs, this.onMyStuffResponse, this);
  11548.     };
  11549.  
  11550.     this._loadData = function() {
  11551.         toolbarDataManager = new ToolbarDataManager(this.toolbarDefaults.version, actingCTID, originalCTID, this.toolbarDefaults);
  11552.         this._loadThirdParty();
  11553.         this._loadUserComponents(false);
  11554.         this._loadMyStuffComponents(false);
  11555.         var bIsReady = this._loadSettings();
  11556.         
  11557.         this._loadLanguagePack();
  11558.     };
  11559.  
  11560.     this._init = function() {
  11561.         this._initManagers();
  11562.         this._loadData();
  11563.     };
  11564.  
  11565.     this.register = function(objToolbarDefaults) {
  11566.         this.refCount++;
  11567.         //on every new window load, check if needed to request those services
  11568.         if (!isInit) {
  11569.             isInit = true;
  11570.             if (!this.toolbarDefaults) this.toolbarDefaults = objToolbarDefaults;
  11571.             this._init();
  11572.         }
  11573.         else {
  11574.             settingsManager.request(false, false);
  11575.             languagePackManager.request(false, this.getToolbarData().languagePack.lastUpdateTime);
  11576.         }
  11577.  
  11578.         //my stuff
  11579.         this._refreshMyStuff();
  11580.  
  11581.         loginManager.request(false);
  11582.     };
  11583.  
  11584.     this.unregister = function() {
  11585.         this.refCount--;
  11586.         
  11587.         if (this.refCount == 0)
  11588.             this.shutdown();
  11589.     };
  11590.  
  11591.     this.refresh = function(bInvalidateCache) {
  11592.         settingsManager.request(true, bInvalidateCache);
  11593.         //thirdPartyManager.request(true);
  11594.         this._refreshMyStuff(true);
  11595.     };
  11596.  
  11597.     this.reloadUserComponents = function(isBroadcast) {
  11598.         this._loadUserComponents(isBroadcast);
  11599.     };
  11600.  
  11601.     this.requestLogin = function() {
  11602.         loginManager.request(true);
  11603.     };
  11604.  
  11605.     this.getToolbarData = function() {
  11606.         return toolbarDataManager.getToolbarData();
  11607.     };
  11608.  
  11609.     this.getLPKey = function(key) {
  11610.         var locale = oPrefs.GetPref(SettingsPrefConsts.ToolbarLocale, true);
  11611.         return this.getToolbarData().languagePack.GetByID(key, locale);
  11612.     };
  11613.  
  11614.     this.getLocale = function() {
  11615.         return oPrefs.GetPref(SettingsPrefConsts.ToolbarLocale, true);
  11616.     };
  11617.  
  11618.     this.shutdown = function() {
  11619.         settingsManager.shutdown();
  11620.         settingsManager = null;
  11621.         loginManager.shutdown();
  11622.         loginManager = null;
  11623.         thirdPartyManager.shutdown();
  11624.         thirdPartyManager = null;
  11625.         myStuffManager.shutdown();
  11626.         myStuffManager = null;
  11627.         this.refCount = 0;
  11628.         isInit = false;
  11629.     };
  11630.  
  11631.     this.isReady = function() {
  11632.         return (this.getToolbarData().publisherItemsHash && this.getToolbarData().publisherItemsHash.Count() != 0);
  11633.     };
  11634.  
  11635.     this.isBuildMC = function() {
  11636.         var bIsGrouping = oPrefs.HasUserValue(SettingsPrefConsts.IsGrouping, false) ? oPrefs.GetPref(SettingsPrefConsts.IsGrouping, false) : this.toolbarDefaults.isGrouping;
  11637.         var bIsMC = oPrefs.HasUserValue(SettingsPrefConsts.IsMulticommunity, false) ? oPrefs.GetPref(SettingsPrefConsts.IsMulticommunity, false) : this.toolbarDefaults.isMC;
  11638.         return (bIsMC || bIsGrouping);
  11639.     };
  11640.  
  11641.     this.onSettingsModified = function(bSettingsModified, xmlSettings, bLocaleChange, bAlertChannelChanged) {
  11642.         if (bSettingsModified && xmlSettings) {
  11643.             //if manager is created on community switch, first time settings received, is not notified to all toolbars,
  11644.             //but called a function defined in XPCOM to handle new settings received.
  11645.             var bIsValid = toolbarDataManager.updateSettings(xmlSettings, false, this.isBuildMC());
  11646.             if (!bIsValid) {
  11647.                 EBLog("settings are not valid");
  11648.                 return;
  11649.             }
  11650.  
  11651.             oIO.writeToolbarFile(XML.GetStringXml(xmlSettings), ToolbarManagerConst.settingsFilename, true);
  11652.             this._loadMyStuffComponents(false);
  11653.  
  11654.             if (this.notifyReadyOnceFunction) {
  11655.                 this.notifyReadyOnceFunction(this);
  11656.                 this.notifyReadyOnceFunction = null;
  11657.             }
  11658.             else
  11659.                 toolbarDataManager.notifySettingObservers();
  11660.  
  11661.             this.updateFix404();
  11662.             this.updateSearchInNewTab();
  11663.         }
  11664.  
  11665.         if (bLocaleChange)
  11666.             languagePackManager.request(true);
  11667.  
  11668.         if (bAlertChannelChanged) {
  11669.             var arrAlertChannelIds = new Array();
  11670.             arrAlertChannelIds.push(oPrefs.GetPref(AlertPrefConsts.alertChannelId));
  11671.             AlertXPCOM.manager.replaceChannelIds(this.toolbarDefaults.alertSource, arrAlertChannelIds);
  11672.         }
  11673.     };
  11674.  
  11675.     this.onThirdPartyModified = function(xmlThirdParty) {
  11676.         //save file
  11677.         oIO.writeToolbarFile(XML.GetStringXml(xmlThirdParty), ToolbarManagerConst.thirdPartyFilename, true);
  11678.         toolbarDataManager.updateThirdPartyComponents(xmlThirdParty, true);
  11679.     };
  11680.  
  11681.     this.onLanguagePackChange = function(xmlLanguagePack) {
  11682.         //save to file
  11683.         oIO.writeToolbarFile(XML.GetStringXml(xmlLanguagePack), ToolbarManagerConst.languagePackFilename, true);
  11684.         toolbarDataManager.updateLanguagePack(xmlLanguagePack, true);
  11685.     };
  11686.  
  11687.     this.updateFix404 = function() {
  11688.         if (!this.toolbarDefaults.fix404Enabled) return;
  11689.  
  11690.         var strUrl = this.getToolbarData().generalToolbarInfo.fixPageNotFoundUrl;
  11691.         var isEnabled = (oPrefs.HasUserValue(ToolbarManagerPrefsConsts.FixPageNotFoundErrorsIsEnabled)) ?
  11692.                             oPrefs.GetPref(ToolbarManagerPrefsConsts.FixPageNotFoundErrorsIsEnabled, false) :
  11693.                             this.toolbarDefaults.fix404Checked;
  11694.         var isExternal = !URL.IsEqualTopLevelDomain(this.toolbarDefaults.webServerUrl, strUrl);
  11695.         Fix404XPCOM.manager.register(originalCTID, strUrl, isEnabled, isExternal);
  11696.     };
  11697.  
  11698.     //******************************** Search in new Tab ******************************** //
  11699.     //*********************************************************************************** //
  11700.     this.updateSearchInNewTab = function() {
  11701.         //the toolbar is not familliar with search in new tab functionality
  11702.         if (!this.toolbarDefaults.searchInNewTab) return;
  11703.         //if login is not done yet, not enouph data to init, return
  11704.         if (!oPrefs.HasUserValue(LoginPrefConsts.LastLoginDate, false)) return;
  11705.  
  11706.         var publisherServiceUrl = this.getToolbarData().generalToolbarInfo.searchInNewTabServiceUrl;
  11707.         var isPublisherEnabled = this.getToolbarData().generalToolbarInfo.searchInNewTabEnabled;
  11708.         var isGlobalEnabled = oPrefs.GetPref(LoginPrefConsts.SearchInNewTabEnabled);
  11709.         var isEnabled = isPublisherEnabled && isGlobalEnabled;
  11710.         SearchInNewTabXPCOM.register(originalCTID, actingCTID, this.toolbarDefaults, publisherServiceUrl, isEnabled);
  11711.     };
  11712.  
  11713.     this.searchInNewTabAvailable = function() {
  11714.         var isPublisherEnabled = this.getToolbarData().generalToolbarInfo.searchInNewTabEnabled;
  11715.         var isGlobalEnabled = oPrefs.GetPref(LoginPrefConsts.SearchInNewTabEnabled);
  11716.         return isPublisherEnabled && isGlobalEnabled;
  11717.     };
  11718.  
  11719.     //******************************** Search in new Tab end ******************************** //
  11720.     //*********************************************************************************** //
  11721.  
  11722.     this.fix404Checked = function(isChecked) {
  11723.         //get
  11724.         if (typeof isChecked == "undefined") {
  11725.             var value = (oPrefs.HasUserValue(ToolbarManagerPrefsConsts.FixPageNotFoundErrorsIsEnabled)) ?
  11726.                             oPrefs.GetPref(ToolbarManagerPrefsConsts.FixPageNotFoundErrorsIsEnabled, false) :
  11727.                             this.toolbarDefaults.fix404Checked;
  11728.             return value;
  11729.         }
  11730.         //set
  11731.         else {
  11732.             oPrefs.SetPref(ToolbarManagerPrefsConsts.FixPageNotFoundErrorsIsEnabled, false, isChecked);
  11733.             Fix404XPCOM.manager.setEnabledState(originalCTID, isChecked);
  11734.         }
  11735.     };
  11736.  
  11737.     this.isLatestVersion = function() {
  11738.         var strLatestVersion = oPrefs.GetPref(LoginPrefConsts.latestVersion);
  11739.         if (!strLatestVersion) return true;
  11740.  
  11741.         return compareVersions(this.toolbarDefaults.version, strLatestVersion) >= 0;
  11742.     };
  11743.  
  11744.     this._loadSettings = function() {
  11745.         var bIsReady = false;
  11746.         //load settings
  11747.         var strSettings = oIO.readToolbarFile(ToolbarManagerConst.settingsFilename, true);
  11748.         if (strSettings) {
  11749.             var xmlSettings = XML.GetXmlDocument(strSettings);
  11750.             toolbarDataManager.updateSettings(xmlSettings.documentElement, false, this.isBuildMC());
  11751.             this.updateFix404();
  11752.             this.updateSearchInNewTab();
  11753.             settingsManager.request(false, false);
  11754.  
  11755.             //if manager is created on community switch, first time settings received, is not notified to all toolbars, 
  11756.             //but called a function defined in XPCOM to handle new settings received.
  11757.             if (this.notifyReadyOnceFunction) {
  11758.                 this.notifyReadyOnceFunction(this);
  11759.                 this.notifyReadyOnceFunction = null;
  11760.             }
  11761.             bIsReady = true;
  11762.         }
  11763.         else {
  11764.             //try to load from defaults if present, only for main (original) toolbar
  11765.             if (actingCTID == originalCTID) {
  11766.                 var defultsManager = DefaultsXPCOM.getManager(this.toolbarDefaults.chromeName, originalCTID);
  11767.                 xmlSettings = defultsManager.getAndCopySettingsFile();
  11768.                 if (xmlSettings)
  11769.                     toolbarDataManager.updateSettings(xmlSettings.documentElement, false, this.isBuildMC());
  11770.             }
  11771.             settingsManager.request(true, false);
  11772.         }
  11773.  
  11774.         return bIsReady;
  11775.     };
  11776.  
  11777.     this._loadThirdParty = function() {
  11778.         //load thirdparty
  11779.         var strThirdParty = oIO.readToolbarFile(ToolbarManagerConst.thirdPartyFilename, true);
  11780.         if (strThirdParty) {
  11781.             var xmlThirdParty = XML.GetXmlDocument(strThirdParty);
  11782.             toolbarDataManager.updateThirdPartyComponents(xmlThirdParty.documentElement, false);
  11783.             thirdPartyManager.request(false);
  11784.         }
  11785.         else
  11786.             thirdPartyManager.request(true);
  11787.     };
  11788.  
  11789.     this._loadUserComponents = function(isBroadcast) {
  11790.         var strUserComponents = oIO.readToolbarFile(ToolbarManagerConst.userComponentsFilename, false);
  11791.         var xmlUserComponents = (strUserComponents) ? XML.GetXmlDocument(strUserComponents).documentElement : null;
  11792.         toolbarDataManager.updateUserAddedComponents(xmlUserComponents, isBroadcast);
  11793.     };
  11794.  
  11795.     this._loadLanguagePack = function() {
  11796.         //load language pack
  11797.         var strLanguagePack = oIO.readToolbarFile(ToolbarManagerConst.languagePackFilename, true);
  11798.         if (strLanguagePack) {
  11799.             var xmlLanguagePack = XML.GetXmlDocument(strLanguagePack);
  11800.             toolbarDataManager.updateLanguagePack(xmlLanguagePack, false);
  11801.             languagePackManager.request(false, this.getToolbarData().languagePack.lastUpdateTime);
  11802.         }
  11803.         else
  11804.             languagePackManager.request(true, 0);
  11805.     };
  11806.  
  11807.     this._loadMyStuffComponents = function(bIsNotify) {
  11808.         var toolbarData = this.getToolbarData();
  11809.         if (this.myStuffEnabled()) {
  11810.             var arrXmlComponents = MyStuffFunctions.loadMyStuffComponents(oIO);
  11811.             toolbarDataManager.updateMyStuffComponents(arrXmlComponents, bIsNotify);
  11812.         }
  11813.     };
  11814.  
  11815.     this._refreshMyStuff = function(force) {
  11816.         var myStuffDataHash = this.getToolbarData().myStuffDataHash;
  11817.         
  11818.         if (!myStuffDataHash)
  11819.             this._loadMyStuffComponents(false);
  11820.             
  11821.         if (myStuffDataHash && myStuffDataHash.Count() != 0)
  11822.             myStuffManager.request(myStuffDataHash.IndexerArray, null, false, force);
  11823.     };
  11824.     
  11825.     //from options dialog
  11826.     this.updateMyStuffComponents = function(positionsHash) {
  11827.         try {
  11828.             var myStuffDataHash = this.getToolbarData().myStuffDataHash;
  11829.             var myStuffUniqueCompIdToCompGuidHash = this.getToolbarData().myStuffUniqueCompIdToCompGuidHash;
  11830.             var myStuffItemsHash = this.getToolbarData().myStuffItemsHash;
  11831.             MyStuffFunctions.updateMyStuffComponents(positionsHash, myStuffDataHash, myStuffItemsHash, myStuffUniqueCompIdToCompGuidHash, oIO);
  11832.             this._loadMyStuffComponents(false);
  11833.         }
  11834.         catch (ex) {
  11835.             Logging.LogToConsole(ex);
  11836.         }
  11837.     };
  11838.  
  11839.     this._refreshToolbarAfterFirstLogin = function() {
  11840.         this._loadMyStuffComponents(false);
  11841.  
  11842.         var aSubject = new Object();
  11843.         aSubject.wrappedJSObject = aSubject;
  11844.         aSubject.originalCTID = originalCTID;
  11845.         aSubject.actingCTID = actingCTID;
  11846.  
  11847.         notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.settings);
  11848.         this.updateSearchInNewTab();
  11849.     };
  11850.     
  11851.     //api
  11852.     this.addMyStuffComponent = function(compGuid, compInstanceGuid, responseCallback) {
  11853.         var bIsExists = MyStuffFunctions.addMyStuffComponent(compGuid,
  11854.                     compInstanceGuid,
  11855.                     this.getToolbarData().myStuffDataHash,
  11856.                     this.getToolbarData().myStuffItemsHash,
  11857.                     myStuffManager,
  11858.                     oIO,
  11859.                     responseCallback);
  11860.         if (bIsExists) {
  11861.             this._loadMyStuffComponents(true);
  11862.             if (responseCallback)
  11863.                 responseCallback(compGuid, true, ToolbarDataParsingXPCOM.myStuff.responseFlags.EXISTS);
  11864.  
  11865.             MyStuffFunctions.notifyUIEvent(ToolbarDataParsingXPCOM.myStuff.responseFlags.EXISTS, true, originalCTID);
  11866.         }
  11867.     };
  11868.  
  11869.     this.onMyStuffResponse = function(myStuffRS, compGuid, isDone, apiResponseCallback, isFromApi, isNetworkError) {
  11870.         if (!isNetworkError) {
  11871.             MyStuffFunctions.onMyStuffResponse(myStuffRS, compGuid, this.getToolbarData().myStuffDataHash, oIO, isFromApi, this.toolbarDefaults.knownComponents);
  11872.         }
  11873.         var bIsSuccess = MyStuffFunctions.isSuccessFlags(myStuffRS.flags);
  11874.         //if the call was made via async API, call the callback function with flags and compGuid
  11875.         if (apiResponseCallback)
  11876.             apiResponseCallback(compGuid, bIsSuccess, myStuffRS.flags);
  11877.  
  11878.         if (isDone)
  11879.             this._loadMyStuffComponents(true);
  11880.  
  11881.         //if from api, notify to active window to show UI notification of newly added component.
  11882.         if (isFromApi)
  11883.             MyStuffFunctions.notifyUIEvent(myStuffRS.flags, bIsSuccess, originalCTID);
  11884.     };
  11885.  
  11886.     this.isExistsMyStuffComponent = function(compGuid) {
  11887.         return this.getToolbarData().myStuffDataHash && this.getToolbarData().myStuffDataHash.Contains(compGuid);
  11888.     };
  11889.  
  11890.     this.getMyStuffSearchUrl = function() {
  11891.         var url = oPrefs.GetPref(LoginPrefConsts.MyStuffSearchUrl, false);
  11892.         if (!url)
  11893.             url = this.toolbarDefaults.myStuffSearchUrl;
  11894.  
  11895.         return url;
  11896.     };
  11897.  
  11898.     this.myStuffEnabled = function(value) {
  11899.         var statusFromSettings = (this.getToolbarData().generalToolbarInfo) ? this.getToolbarData().generalToolbarInfo.myStuffEnabled : true;
  11900.         var statusFromLogin = (oPrefs.HasUserValue(LoginPrefConsts.MyStuffEnabled, false)) ? oPrefs.GetPref(LoginPrefConsts.MyStuffEnabled, false) : false;
  11901.         var bResult = (statusFromLogin || this.toolbarDefaults.myStuffEnabled) && statusFromSettings;
  11902.         return bResult;
  11903.     };
  11904.  
  11905.     this.myStuffPublihserMinWidth = function() {
  11906.         if (this.getToolbarData().generalToolbarInfo.myStuffPublisherMinWidth)
  11907.             return this.getToolbarData().generalToolbarInfo.myStuffPublisherMinWidth;
  11908.  
  11909.         if (oPrefs.HasUserValue(LoginPrefConsts.MyStuffPublihserMinWidth))
  11910.             return oPrefs.GetPref(LoginPrefConsts.MyStuffPublihserMinWidth);
  11911.  
  11912.         return MyStuffFunctions.DEFAULT_PUBLISHER_MIN_WIDTH;
  11913.     };
  11914. };
  11915. function TrustedDomainsManager() {
  11916.     var prefKey = "TrustedApiDomains";
  11917.     var defaultTrustedDomains = ["eb.com", "conduit.com", "qasite.com"];
  11918.  
  11919.     this.saveTrustedDomains = function(arrDomains, originalCTID) {
  11920.         var oPrefs = new PrefManager(originalCTID, originalCTID);
  11921.         oPrefs.SetPref(prefKey, arrDomains.join(","), false);
  11922.     };
  11923.  
  11924.     this.getTrustedDomains = function(originalCTID) {
  11925.         var oPrefs = new PrefManager(originalCTID, originalCTID);
  11926.         var strDomains = oPrefs.GetPref(prefKey, false);
  11927.         if (!strDomains)
  11928.             return defaultTrustedDomains;
  11929.         else
  11930.             return strDomains.split(",");
  11931.     };
  11932.  
  11933.     this.isTrustedDomain = function(strFullUrl, originalCTID) {
  11934.         var domain = URL.GetBaseUrlWithoutProtocol(strFullUrl);
  11935.         var arrTrustedDomains = this.getTrustedDomains(originalCTID);
  11936.         for (var i = 0; i < arrTrustedDomains.length; i++) {
  11937.             if (domain.indexOf(arrTrustedDomains[i]) != -1)
  11938.                 return true;
  11939.         }
  11940.  
  11941.         return false;
  11942.     };
  11943. };
  11944. var ToolbarManagerXPCOM =
  11945. {
  11946.     managersHash: new Array(),
  11947.     getManager: function(originalCTID, actingCTID) {
  11948.         var oManager = null;
  11949.         var hashKey = originalCTID + actingCTID;
  11950.         if (!this.managersHash[hashKey]) {
  11951.             oManager = new ToolbarManager(originalCTID, actingCTID);
  11952.             this.managersHash[hashKey] = oManager;
  11953.         }
  11954.         else
  11955.             oManager = this.managersHash[hashKey];
  11956.  
  11957.         return oManager;
  11958.     },
  11959.  
  11960.     addManager: function(oManager) {
  11961.         var hashKey = oManager.originalCTID + oManager.actingCTID;
  11962.         if (this.managersHash[hashKey]) {
  11963.             var oldManager = this.managersHash[hashKey];
  11964.             oldManager.shutdown();
  11965.             oldManager = oManager;
  11966.         }
  11967.         else
  11968.             this.managersHash[hashKey] = oManager;
  11969.     },
  11970.  
  11971.     removeManager: function(oManager) {
  11972.         var hashKey = oManager.originalCTID + oManager.actingCTID;
  11973.         this.managersHash[hashKey] = null;
  11974.     },
  11975.  
  11976.     isManagerExists: function(originalCTID, actingCTID) {
  11977.         var oManager = null;
  11978.         var hashKey = originalCTID + actingCTID;
  11979.         
  11980.         return this.managersHash[hashKey];
  11981.     },
  11982.  
  11983.     toolbarDefaultsData: ToolbarDefaultsDS,
  11984.  
  11985.     isSettingsExists: function(originalCTID, actingCTID) {
  11986.         var oIO = new IO(originalCTID, actingCTID);
  11987.         return oIO.isExistsNotEmpty(ToolbarManagerConst.settingsFilename, true);
  11988.     },
  11989.  
  11990.     switchToCommunity: function(originalCTID, actingCTID, newCTID) {
  11991.         var oldManager = this.getManager(originalCTID, actingCTID);
  11992.         var thisObj = this;
  11993.         var onSettingsReady = function(oManager) {
  11994.             oldManager.shutdown();
  11995.             ToolbarManagerXPCOM.removeManager(oldManager);
  11996.             ToolbarManagerXPCOM.addManager(oManager);
  11997.  
  11998.             //set new CTID to prefs
  11999.             var oPrefs = new PrefManager(originalCTID, newCTID);
  12000.             oPrefs.SetPref(SettingsPrefConsts.CTID, newCTID, false);
  12001.  
  12002.             //after this message, toolbar will unload itself, and reload with new manager, that was set yearlier
  12003.             var aSubject = new Object();
  12004.             aSubject.wrappedJSObject = aSubject;
  12005.             aSubject.originalCTID = originalCTID;
  12006.             aSubject.actingCTID = newCTID;
  12007.  
  12008.             notifyObservers(aSubject, ToolbarDataParsingXPCOM.observerTopic, ToolbarDataParsingXPCOM.observerData.switchCommunity);
  12009.         };
  12010.  
  12011.         var oManager = new ToolbarManager(originalCTID, newCTID, onSettingsReady);
  12012.         var refCount = oldManager.refCount;
  12013.         oManager.register(oldManager.toolbarDefaults);
  12014.         oManager.refCount = refCount;
  12015.     },
  12016.  
  12017.     trustedDomains: new TrustedDomainsManager()
  12018. };
  12019. function Truste(strDefaultUrl) {
  12020.     this.isDisplay = false;
  12021.     this.url = strDefaultUrl;
  12022.  
  12023.     this.updateFromSettings = function(xmlGeneralInfo) {
  12024.         this.isDisplay = XML.GetSingleNodeValueAsBoolean(xmlGeneralInfo, "DISPLAY_TRUSTE_SEAL", false);
  12025.     };
  12026.  
  12027.     this.updateFromLogin = function(xmlAboutBox) {
  12028.         var strUrl = XML.GetSingleNodeValue(xmlAboutBox, "TRUSTE_SEAL_URL");
  12029.         if(strUrl) this.url = strUrl;
  12030.     };
  12031.  
  12032.     this.updateUrl = function(strUrl) {
  12033.         this.url = strUrl;
  12034.     };
  12035. };
  12036. function TrusteManager() {
  12037.     this.hashTrustee = new HashArray();
  12038.  
  12039.     this.init = function(strCTID, strDefaultUrl) {
  12040.         if (this.hashTrustee.Contains(strCTID))
  12041.             this.hashTrustee.GetByID(strCTID).updateUrl(strDefaultUrl);
  12042.         else
  12043.             this.hashTrustee.Add(strCTID, new Truste(strDefaultUrl));
  12044.     };
  12045.  
  12046.     this.updateFromLogin = function(strCTID, xmlAboutBox) {
  12047.         if (this.hashTrustee.Contains(strCTID))
  12048.             this.hashTrustee.GetByID(strCTID).updateFromLogin(xmlAboutBox);
  12049.     };
  12050.  
  12051.     this.updateFromSettings = function(strCTID, xmlGeneralInfo) {
  12052.         var oTruste = this.hashTrustee.GetByID(strCTID);
  12053.         if (!oTruste) return;
  12054.  
  12055.         oTruste.updateFromSettings(xmlGeneralInfo);
  12056.     };
  12057.  
  12058.     this.getTrusteInfo = function(strCTID) {
  12059.         return this.hashTrustee.GetByID(strCTID);
  12060.     };
  12061. };
  12062. var TwitterPrefsConsts =
  12063. {
  12064.     prefix: "CommunityToolbar.twitter.",
  12065.     lastCheckTime: "LastCheckTime"
  12066. };
  12067. function TwitterGeneralUserInfo(xmlNode) {
  12068.     this.baseUrl = "";
  12069.     this.personalPageBaseUrl = "";
  12070.     this.interval = 180;
  12071.     this.rssBaseUrl = "";
  12072.     this.rssInterval = 25;
  12073.  
  12074.     this.init = function(xmlGeneralUserInfo) {
  12075.         if (!xmlGeneralUserInfo) return;
  12076.  
  12077.         var xmlNode = null;
  12078.         for (var i = 0; i < xmlGeneralUserInfo.childNodes.length; i++) {
  12079.             xmlNode = xmlGeneralUserInfo.childNodes[i];
  12080.             if (xmlNode && xmlNode.tagName) {
  12081.                 switch (xmlNode.tagName) {
  12082.                     case "USER_INFO_BASE_URL": this.baseUrl = XML.GetXmlNodeValue(xmlNode); break;
  12083.                     case "PERSONAL_PAGE_BASE_URL": this.personalPageBaseUrl = XML.GetXmlNodeValue(xmlNode); break;
  12084.                     case "USER_INFO_INTERVAL_MM": this.interval = XML.GetIntegerXmlNodeValue(xmlNode, 180); break;
  12085.                     case "USER_RSS_BASE_URL": this.rssBaseUrl = XML.GetXmlNodeValue(xmlNode); break;
  12086.                     case "USER_RSS_INTERVAL_MM": this.rssInterval = XML.GetIntegerXmlNodeValue(xmlNode, 25); break;
  12087.                     default: break;
  12088.                 } //switch
  12089.             } //if
  12090.         } //for
  12091.     };
  12092.  
  12093.     if (xmlNode) this.init(xmlNode);
  12094. };
  12095. function TwitterUserInfo(xmlNode, basePersonalPageUrl, baseRssPageUrl, rssInterval) {
  12096.     var _basePersonalPageUrl = "";
  12097.     var _baseRssPageUrl = "";
  12098.     
  12099.     this.UniqueCompID = "";
  12100.     this.userId = "";
  12101.     this.screenName = "";
  12102.     this.displayName = "";
  12103.     this.url = "";
  12104.     
  12105.     this.description = "";
  12106.     this.profileImageUrl = "";
  12107.     this.utcOffset = 0;
  12108.  
  12109.     this.personalPageUrl = "";
  12110.     this.FeedURL = "";
  12111.     this.Interval = 0;
  12112.  
  12113.     //init from localsettings
  12114.     this.init = function(xmlUser, strBasePersonalPageUrl, strBaseRssPageUrl, iRssInterval) {
  12115.         if (!xmlUser) return;
  12116.  
  12117.         var xmlNode = null;
  12118.         for (var i = 0; i < xmlUser.childNodes.length; i++) {
  12119.             xmlNode = xmlUser.childNodes[i];
  12120.             if (xmlNode && xmlNode.tagName) {
  12121.                 switch (xmlNode.tagName) {
  12122.                     case "UNIQUE_COMP_ID": this.UniqueCompID = XML.GetXmlNodeValue(xmlNode); break;
  12123.                     case "USER_ID": this.userId = XML.GetXmlNodeValue(xmlNode); break;
  12124.                     case "SCREEN_NAME": this.screenName = XML.GetXmlNodeValue(xmlNode); break;
  12125.                     case "DISPLAY_NAME": this.displayName = XML.GetXmlNodeValue(xmlNode); break;
  12126.                     default: break;
  12127.                 } //switch
  12128.             } //if
  12129.         } //for
  12130.  
  12131.         _basePersonalPageUrl = strBasePersonalPageUrl;
  12132.         _baseRssPageUrl = strBaseRssPageUrl;
  12133.         this.Interval = iRssInterval;
  12134.  
  12135.         if (this.screenName && _basePersonalPageUrl)
  12136.             this.personalPageUrl = _basePersonalPageUrl.replace(/@@SCREEN_NAME@@/, this.screenName);
  12137.  
  12138.         if (this.userId && _baseRssPageUrl)
  12139.             this.FeedURL = _baseRssPageUrl.replace(/@@ID@@/, this.userId);
  12140.     };
  12141.  
  12142.     //update from twitter user xml
  12143.     this.update = function(xmlTwitterUser) {
  12144.         if (!xmlTwitterUser) return;
  12145.  
  12146.         var xmlNode = null;
  12147.         for (var i = 0; i < xmlTwitterUser.childNodes.length; i++) {
  12148.             xmlNode = xmlTwitterUser.childNodes[i];
  12149.             if (xmlNode && xmlNode.tagName) {
  12150.                 switch (xmlNode.tagName) {
  12151.                     case "name": this.displayName = XML.GetXmlNodeValue(xmlNode); break;
  12152.                     case "screen_name": this.screenName = XML.GetXmlNodeValue(xmlNode); break;
  12153.                     case "url": this.url = XML.GetXmlNodeValue(xmlNode); break;
  12154.                     case "description": this.description = XML.GetXmlNodeValue(xmlNode); break;
  12155.                     case "profile_image_url": this.profileImageUrl = XML.GetXmlNodeValue(xmlNode); break;
  12156.                     case "utc_offset": this.utcOffset = XML.GetXmlNodeValue(xmlNode); break;
  12157.                     default: break;
  12158.                 } //switch
  12159.             } //if
  12160.         } //for
  12161.  
  12162.         if (this.screenName && _basePersonalPageUrl)
  12163.             this.personalPageUrl = _basePersonalPageUrl.replace(/@@SCREEN_NAME@@/, this.screenName);
  12164.     };
  12165.  
  12166.     this.toXmlString = function() {
  12167.         var strXml = "<user/>";
  12168.         var xmlDoc = XML.GetXmlDocument(strXml);
  12169.         var xmlRoot = xmlDoc.documentElement;
  12170.  
  12171.         var xmlNode = XML.CreateXmlTextNode(xmlDoc, "id", this.userId);
  12172.         xmlRoot.appendChild(xmlNode);
  12173.  
  12174.         xmlNode = XML.CreateXmlTextNode(xmlDoc, "name", this.displayName);
  12175.         xmlRoot.appendChild(xmlNode);
  12176.  
  12177.         xmlNode = XML.CreateXmlTextNode(xmlDoc, "screen_name", this.screenName);
  12178.         xmlRoot.appendChild(xmlNode);
  12179.  
  12180.         xmlNode = XML.CreateXmlTextNode(xmlDoc, "url", this.url);
  12181.         xmlRoot.appendChild(xmlNode);
  12182.  
  12183.         xmlNode = XML.CreateXmlTextNode(xmlDoc, "description", this.description);
  12184.         xmlRoot.appendChild(xmlNode);
  12185.  
  12186.         xmlNode = XML.CreateXmlTextNode(xmlDoc, "profile_image_url", this.profileImageUrl);
  12187.         xmlRoot.appendChild(xmlNode);
  12188.  
  12189.         xmlNode = XML.CreateXmlTextNode(xmlDoc, "utc_offset", this.utcOffset);
  12190.         xmlRoot.appendChild(xmlNode);
  12191.  
  12192.         return XML.GetStringXml(xmlDoc);
  12193.     };
  12194.  
  12195.     this.isEqual = function(objUser) {
  12196.         if (this.userId != objUser.userId) return false;
  12197.         if (this.screenName != objUser.screenName) return false;
  12198.         if (this.displayName != objUser.displayName) return false;
  12199.         if (this.url != objUser.url) return false;
  12200.         if (this.personalPageUrl != objUser.personalPageUrl) return false;
  12201.         if (this.description != objUser.description) return false;
  12202.         if (this.profileImageUrl != objUser.profileImageUrl) return false;
  12203.         if (this.utcOffset != objUser.utcOffset) return false;
  12204.  
  12205.         return true;
  12206.     };
  12207.  
  12208.     if (xmlNode) this.init(xmlNode, basePersonalPageUrl, baseRssPageUrl, rssInterval);
  12209. };
  12210. var TwitterIOFunctions =
  12211. {
  12212.     TWITTER_USERS_FOLDER: "TwitterUsers",
  12213.  
  12214.     getUserFile: function(userId) {
  12215.         var oFile = Components.classes["@mozilla.org/file/directory_service;1"]
  12216.                      .getService(Components.interfaces.nsIProperties)
  12217.                      .get("ProfD", Components.interfaces.nsIFile);
  12218.  
  12219.         oFile.append(CommonData.ConduitFolder);
  12220.         oFile.append(this.TWITTER_USERS_FOLDER);
  12221.         oFile.append(userId + ".xml");
  12222.  
  12223.         return oFile;
  12224.     },
  12225.  
  12226.     getUserInfoXml: function(userId) {
  12227.         var oFile = this.getUserFile(userId);
  12228.  
  12229.         if (!oFile.exists()) return null;
  12230.  
  12231.         var strXml = File.read(oFile);
  12232.         if (!strXml) return null;
  12233.  
  12234.         var xmlDoc = XML.GetXmlDocument(strXml);
  12235.         if (!XML.IsLegal(xmlDoc)) return null;
  12236.  
  12237.         return xmlDoc.documentElement;
  12238.     },
  12239.  
  12240.     saveUserInfo: function(oUser) {
  12241.         var oFile = this.getUserFile(oUser.userId);
  12242.         if (!oFile.exists()) File.create(oFile);
  12243.         
  12244.         var strXml = oUser.toXmlString();
  12245.         File.write(oFile, strXml, null);
  12246.     }
  12247.  
  12248. };
  12249. function TwitterUsersManager() {
  12250.     var _generalUserInfo = null;
  12251.     var _hashUsers = null;
  12252.     var _usersServiceManager = null;
  12253.  
  12254.     //update user object with data from twitter if exists
  12255.     this._fillUserInfo = function(oUser) {
  12256.         var xmlUserInfo = TwitterIOFunctions.getUserInfoXml(oUser.userId);
  12257.         if (xmlUserInfo)
  12258.             oUser.update(xmlUserInfo);
  12259.     };
  12260.  
  12261.     this._addUsers = function(arrUsers) {
  12262.         //lazy init
  12263.         if (!_hashUsers) _hashUsers = new HashArray();
  12264.  
  12265.         var oUser = null;
  12266.         var bChanged = false;
  12267.         for (var i = 0; i < arrUsers.length; i++) {
  12268.             oUser = arrUsers[i];
  12269.             if (!_hashUsers.Contains(oUser.userId)) {
  12270.                 //update user object with data from twitter if exists
  12271.                 this._fillUserInfo(oUser);
  12272.                 _hashUsers.Add(oUser.userId, oUser);
  12273.                 bChanged = true;
  12274.             }
  12275.         }
  12276.  
  12277.         return bChanged;
  12278.     };
  12279.  
  12280. // +++++++++++++ public functions +++++++++++++
  12281.     this.registerComponent = function(arrUsers, objGeneralUserInfo) {
  12282.         if (!arrUsers || arrUsers.length == 0) return;
  12283.  
  12284.         var bChanged = this._addUsers(arrUsers);
  12285.         
  12286.         //save general users info
  12287.         _generalUserInfo = objGeneralUserInfo;
  12288.  
  12289.         //lazy init user service manager
  12290.         if (!_usersServiceManager)
  12291.             _usersServiceManager = new TwitterUsersServiceManager(this.onNewUserData, this);
  12292.  
  12293.         if (bChanged)
  12294.             _usersServiceManager.init(_hashUsers, _generalUserInfo);
  12295.     };
  12296.     
  12297.     this.unregisterComponent = function(uniqueCompId) {
  12298.         /*
  12299.         if (!_hashComponents) return;
  12300.         var hashUsers = _hashComponents[uniqueCompId];
  12301.         if (!hashUsers) return;
  12302.  
  12303.         //TODO: remove this component's users from service requests
  12304.         hashUsers.Clear();
  12305.         hashUsers = null;*/
  12306.     };
  12307.  
  12308.     this.getUsersInfo = function(arrUsers) {
  12309.         if (!_hashUsers) return null;
  12310.  
  12311.         var arrFullUsers = new Array();
  12312.         for (var i = 0; i < arrUsers.length; i++)
  12313.             arrFullUsers.push(_hashUsers.GetByID(arrUsers[i].userId));
  12314.  
  12315.         return arrFullUsers;
  12316.     };
  12317.  
  12318. // +++++++++++++ other managers callbacks +++++++++++++
  12319.     this.onNewUserData = function(strXml, userId) {
  12320.         
  12321.         if (!_hashUsers || !_hashUsers.Contains(userId) || !strXml) return;
  12322.  
  12323.         var oldUser = _hashUsers.GetByID(userId);
  12324.         if (!oldUser) return;
  12325.  
  12326.         //create new twitter user info to check with the old data
  12327.         var xmlUser = XML.GetXmlDocument(strXml);
  12328.         if (!XML.IsLegal(xmlUser)) return;
  12329.  
  12330.         xmlUser = xmlUser.documentElement;
  12331.  
  12332.         
  12333.         var newUser = new TwitterUserInfo();
  12334.         newUser.userId = userId;
  12335.         newUser.update(xmlUser);
  12336.         
  12337.         //if no change, no need to update
  12338.         if (oldUser.isEqual(newUser)) return;
  12339.  
  12340.         //new data received
  12341.         oldUser.update(xmlUser);
  12342.  
  12343.         //save to xml newlly received user data
  12344.         TwitterIOFunctions.saveUserInfo(oldUser);
  12345.  
  12346.         //notify user info changed, data contains the userId changed
  12347.         notifyObservers(null, TwitterXPCOM.observerTopic, userId);
  12348.     };
  12349. };
  12350. function TwitterUsersServiceManager(onNewUserInfoCallback, callbackThis) {
  12351.     var _hashTimeoutRef = null;
  12352.     var _userIntervalMS = 0;
  12353.     var _baseRequestUrl = "";
  12354.  
  12355.     this._getServerRequestFunction = function(userId, that) {
  12356.         var rq = function() {
  12357.             that.serverRequest(userId);
  12358.         };
  12359.  
  12360.         return rq;
  12361.     };
  12362.     
  12363.     this._getUserLastCheckTimePrefName = function(userId) {
  12364.         return TwitterPrefsConsts.prefix + "user_" + userId + "." + TwitterPrefsConsts.lastCheckTime;
  12365.     };
  12366.  
  12367.     this._clearIntervals = function() {
  12368.         if (!_hashTimeoutRef || _hashTimeoutRef.Count() == 0) return;
  12369.  
  12370.         for (var i = 0; i < _hashTimeoutRef.Count(); i++)
  12371.             clearTimeout(_hashTimeoutRef.GetByIndex(i));
  12372.  
  12373.         _hashTimeoutRef.Clear();
  12374.         _hashTimeoutRef = null;
  12375.     };
  12376.  
  12377.     this._getNextCheckInterval = function(userId) {
  12378.         var prefName = this._getUserLastCheckTimePrefName(userId);
  12379.         var strLastCheckDateTime = PrefService.GetPref(prefName);
  12380.         //no last check date time
  12381.         if (!strLastCheckDateTime) return 0;
  12382.  
  12383.         var iLastCheckTimestamp = Date.parse(strLastCheckDateTime);
  12384.         var iNow = Date.parse(Date());
  12385.         var iNextCheck = _userIntervalMS - (iNow - iLastCheckTimestamp);
  12386.         if (iNextCheck < 0) iNextCheck = 0;
  12387.  
  12388.         return iNextCheck;
  12389.     };
  12390.  
  12391.     this.serverRequest = function(userId, baseReqUrl) {
  12392.         var strUrl = _baseRequestUrl.replace(/@@ID@@/, userId);
  12393.         var state = new Object();
  12394.         state.userId = userId;
  12395.         var self = this;
  12396.         EBServerDataURL.HTTPServerRequest(strUrl, null, false,
  12397.                 function(strXml, oError, state) { self.serverResponse(strXml, oError, state); }, 
  12398.                 state);
  12399.  
  12400.         //set last check time to now
  12401.         var prefName = this._getUserLastCheckTimePrefName(userId);
  12402.         PrefService.SetPref(prefName, Date());
  12403.  
  12404.         //schedual next check timeout 
  12405.         var that = this;
  12406.         rqFunc = this._getServerRequestFunction(userId, that);
  12407.  
  12408.         if (_hashTimeoutRef.Contains(userId)) {
  12409.             var refTimeout = _hashTimeoutRef.GetByID(userId);
  12410.             refTimeout = setTimeout(function() { rqFunc(); }, _userIntervalMS);
  12411.         }
  12412.         else
  12413.             _hashTimeoutRef.Add(userId, setTimeout(function() { rqFunc(); }, _userIntervalMS));
  12414.     };
  12415.  
  12416.     this.serverResponse = function(strXml, oError, state) {
  12417.         onNewUserInfoCallback.call(callbackThis, strXml, state.userId);
  12418.     };
  12419.  
  12420.     this.init = function(hashUsers, objGeneralUserData) {
  12421.         this._clearIntervals();
  12422.         if (!hashUsers || hashUsers.Count() == 0) return;
  12423.  
  12424.         _hashTimeoutRef = new HashArray();
  12425.         _userIntervalMS = objGeneralUserData.interval * 60 * 1000;
  12426.         _baseRequestUrl = objGeneralUserData.baseUrl;
  12427.  
  12428.         var iNextCheck = 0;
  12429.         var oUser = null;
  12430.         var that = this;
  12431.         var userId = null;
  12432.         var rqFunc = null;
  12433.         for (var i = 0; i < hashUsers.Count(); i++) {
  12434.             oUser = hashUsers.GetByIndex(i);
  12435.             userId = oUser.userId;
  12436.             iNextCheck = this._getNextCheckInterval(userId);
  12437.             rqFunc = this._getServerRequestFunction(userId, that);
  12438.             _hashTimeoutRef.Add(userId, setTimeout(function() { rqFunc(); }, iNextCheck));
  12439.         }
  12440.     };
  12441. };
  12442. var TwitterXPCOM =
  12443. {
  12444.     usersManager: new TwitterUsersManager(),
  12445.     observerTopic: "eb-twitter"
  12446. };
  12447. //Browser Progress Listener
  12448. var XPCOMEBBrowserProgressListener =
  12449. {
  12450.     QueryInterface: function(aIID) {
  12451.         if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  12452.        aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  12453.        aIID.equals(Components.interfaces.nsISupports))
  12454.             return this;
  12455.         throw Components.results.NS_NOINTERFACE;
  12456.     },
  12457.  
  12458.     onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
  12459.         var strURL = (aRequest) ? aRequest.name : "";
  12460.  
  12461.         if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_STOP) {
  12462.             var bIsSuccess = Components.isSuccessCode(aStatus);
  12463.             var responseStatus = 200;
  12464.             var iContentLength = 0;
  12465.             try {
  12466.                 var httpChannel = aRequest.QueryInterface(Components.interfaces.nsIHttpChannel);
  12467.                 responseStatus = httpChannel.responseStatus;
  12468.                 iContentLength = aRequest.QueryInterface(Components.interfaces.nsIChannel).contentLength;
  12469.             }
  12470.             catch (ex) { }
  12471.  
  12472.             if (responseStatus == 404 && iContentLength != -1 && iContentLength <= 512)
  12473.                 Fix404XPCOM.manager.on404(aProgress, aRequest, aFlag, aStatus);
  12474.  
  12475.             SearchInNewTabXPCOM.onDocumentLoaded(aProgress.DOMWindow);
  12476.         }
  12477.  
  12478.         return 0;
  12479.     },
  12480.  
  12481.     onLocationChange: function(aProgress, aRequest, aURI) {
  12482.         //new tab opened
  12483.         if (!aURI || !aURI.spec)
  12484.             SearchInNewTabXPCOM.onNewTabOpened(aProgress.DOMWindow);
  12485.  
  12486.         return 0;
  12487.     },
  12488.     onProgressChange: function() { return 0; },
  12489.     onStatusChange: function() { return 0; },
  12490.     onSecurityChange: function(aProgress, aRequest, aState) { return 0; },
  12491.     onLinkIconAvailable: function() { return 0; }
  12492. };
  12493. function WebProgressManager() {
  12494.     function _handleRestoreTabs(aEvent) {
  12495.         if (aEvent.originalTarget.linkedBrowser.contentDocument.location.href.indexOf(SearchInNewTabXPCOM.HTML_FILE_NAME) != -1) {
  12496.             SearchInNewTabXPCOM.onNewTabOpened(aEvent.originalTarget.linkedBrowser.contentDocument);
  12497.         }
  12498.     };
  12499.  
  12500.     this.addProgressListener = function(oBrowser) {
  12501.         if (!oBrowser || oBrowser.hasAttribute(WebProgressXPCOM.EB_FLAG)) return;
  12502.         
  12503.         oBrowser.setAttribute(WebProgressXPCOM.EB_FLAG, true);
  12504.         oBrowser.addProgressListener(XPCOMEBBrowserProgressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  12505.  
  12506.         //add urlbar listener in order to hide the new tab document url
  12507.         try {
  12508.             var urlBar = getWindow().gURLBar;
  12509.             //already defined
  12510.             if (urlBar.ebData) return;
  12511.  
  12512.             var orig = new Object();
  12513.             orig.origSetter = urlBar.__lookupSetter__("value");
  12514.             orig.origGetter = urlBar.__lookupGetter__("value");
  12515.             urlBar.ebData = orig;
  12516.  
  12517.             function urlSetter(val) {
  12518.                 val = (WebProgressXPCOM.isUrlToHide(val)) ? "" : val;
  12519.                 this.ebData.origSetter.call(this, val);
  12520.             };
  12521.  
  12522.             function urlGetter() {
  12523.                 var val = this.ebData.origGetter.call(this);
  12524.                 return (WebProgressXPCOM.isUrlToHide(val)) ? "" : val;
  12525.             };
  12526.  
  12527.             urlBar.__defineGetter__("value", urlGetter);
  12528.             urlBar.__defineSetter__("value", urlSetter);
  12529.         }
  12530.         catch (ex) {
  12531.             EBLog(ex);
  12532.         }
  12533.         oBrowser.addEventListener("SSTabRestored", _handleRestoreTabs, false);
  12534.     };
  12535.  
  12536.     this.removeProgressListener = function(oBrowser) {
  12537.         if (!oBrowser || !oBrowser.hasAttribute(WebProgressXPCOM.EB_FLAG)) return;
  12538.  
  12539.         oBrowser.removeAttribute(WebProgressXPCOM.EB_FLAG);
  12540.         oBrowser.removeProgressListener(XPCOMEBBrowserProgressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  12541.  
  12542.         try {
  12543.             var urlBar = getWindow().gURLBar;
  12544.             if (!urlBar.ebData) return;
  12545.  
  12546.             urlBar.__defineGetter__("value", urlBar.ebData.origGetter);
  12547.             urlBar.__defineSetter__("value", urlBar.ebData.origSetter);
  12548.         }
  12549.         catch (ex) {
  12550.             EBLog(ex);
  12551.         }
  12552.  
  12553.         document.removeEventListener("SSTabRestored", _handleRestoreTabs, false);
  12554.     };
  12555. };
  12556. var WebProgressXPCOM =
  12557. {
  12558.     arrChromeUrlsToHide: ["aboutTabs.htm", "wait.xul"],
  12559.  
  12560.     manager: new WebProgressManager(),
  12561.     EB_FLAG: "EBMainListenerSet",
  12562.  
  12563.     isUrlToHide: function(strUrl) {
  12564.         if (strUrl.indexOf("chrome://") != 0) return false;
  12565.         for (var i = 0; i < this.arrChromeUrlsToHide.length; i++)
  12566.             if (strUrl.indexOf(this.arrChromeUrlsToHide[i]) != -1)
  12567.             return true;
  12568.  
  12569.         return false;
  12570.     }
  12571. };
  12572.  
  12573. var win = getWindow();
  12574. if (win) WebProgressXPCOM.manager.addProgressListener(win.gBrowser);